Merge remote-tracking branch 'upstream/master'
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -19,7 +19,7 @@ assignees: ''
|
|||||||
|
|
||||||
**Link(s) to mod(s) used**: *The mod repositories or zip files that are related to the issue, if applicable.*
|
**Link(s) to mod(s) used**: *The mod repositories or zip files that are related to the issue, if applicable.*
|
||||||
|
|
||||||
**Save file**: *The save file you were playing on when the bug happened, if applicable.*
|
**Save file**: *The save file you were playing on when the bug happened. REQUIRED for any issue that happens in-game.*
|
||||||
|
|
||||||
**Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.*
|
**Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.*
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public class EntityProcess extends BaseProcessor{
|
|||||||
//replace all self() invocations with this
|
//replace all self() invocations with this
|
||||||
.replaceAll("this\\.<(.*)>self\\(\\)", "this")
|
.replaceAll("this\\.<(.*)>self\\(\\)", "this")
|
||||||
.replaceAll("self\\(\\)", "this")
|
.replaceAll("self\\(\\)", "this")
|
||||||
|
.replaceAll(" yield ", "")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class LogicStatementProcessor extends BaseProcessor{
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for(Svar field : fields){
|
for(Svar field : fields){
|
||||||
if(field.is(Modifier.TRANSIENT)) continue;
|
if(field.isAny(Modifier.TRANSIENT, Modifier.STATIC)) continue;
|
||||||
|
|
||||||
writer.addStatement("out.append(\" \")");
|
writer.addStatement("out.append(\" \")");
|
||||||
writer.addStatement("out.append((($T)obj).$L$L)", c.mirror(), field.name(),
|
writer.addStatement("out.append((($T)obj).$L$L)", c.mirror(), field.name(),
|
||||||
|
|||||||
21
build.gradle
@@ -173,18 +173,29 @@ allprojects{
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile){
|
tasks.withType(JavaCompile){
|
||||||
sourceCompatibility = 1.8
|
targetCompatibility = 8
|
||||||
targetCompatibility = 1.8
|
sourceCompatibility = 14
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
options.compilerArgs += ["-Xlint:deprecation"]
|
options.compilerArgs += ["-Xlint:deprecation"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//compile with java 8 compatibility for everything except the annotati project
|
configure(project(":annotations")){
|
||||||
|
tasks.withType(JavaCompile){
|
||||||
|
targetCompatibility = 8
|
||||||
|
sourceCompatibility = 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//compile with java 8 compatibility for everything except the annotation project
|
||||||
configure(subprojects - project(":annotations")){
|
configure(subprojects - project(":annotations")){
|
||||||
tasks.withType(JavaCompile){
|
tasks.withType(JavaCompile){
|
||||||
if(JavaVersion.current() != JavaVersion.VERSION_1_8){
|
if(JavaVersion.current() != JavaVersion.VERSION_1_8){
|
||||||
options.compilerArgs.addAll(['--release', '8'])
|
options.compilerArgs.addAll(['--release', '8', '--enable-preview'])
|
||||||
|
}
|
||||||
|
|
||||||
|
doFirst{
|
||||||
|
options.compilerArgs = options.compilerArgs.findAll{it != '--enable-preview' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +299,8 @@ project(":core"){
|
|||||||
|
|
||||||
compileOnly project(":annotations")
|
compileOnly project(":annotations")
|
||||||
annotationProcessor project(":annotations")
|
annotationProcessor project(":annotations")
|
||||||
|
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:0.3.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 277 B |
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 277 B |
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 298 B After Width: | Height: | Size: 491 B |
|
Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 499 B |
|
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 522 B |
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 300 B |
|
Before Width: | Height: | Size: 252 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 299 B |
|
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 296 B |
|
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 289 B |
|
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 375 B |
|
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 408 B |
|
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 409 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 640 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 410 B |
|
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 441 B |
|
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 454 B |
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 448 B |
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 1.2 KiB |
BIN
core/assets-raw/sprites/blocks/turrets/foreshadow-heat.png
Normal file
|
After Width: | Height: | Size: 537 B |
BIN
core/assets-raw/sprites/blocks/turrets/foreshadow.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1118,6 +1118,7 @@ block.arc.name = Arc
|
|||||||
block.rtg-generator.name = RTG Generator
|
block.rtg-generator.name = RTG Generator
|
||||||
block.spectre.name = Spectre
|
block.spectre.name = Spectre
|
||||||
block.meltdown.name = Meltdown
|
block.meltdown.name = Meltdown
|
||||||
|
block.foreshadow.name = Foreshadow
|
||||||
block.container.name = Container
|
block.container.name = Container
|
||||||
block.launch-pad.name = Launch Pad
|
block.launch-pad.name = Launch Pad
|
||||||
block.launch-pad-large.name = Large Launch Pad
|
block.launch-pad-large.name = Large Launch Pad
|
||||||
|
|||||||
@@ -311,3 +311,4 @@
|
|||||||
63425=vela|unit-vela-medium
|
63425=vela|unit-vela-medium
|
||||||
63424=corvus|unit-corvus-medium
|
63424=corvus|unit-corvus-medium
|
||||||
63423=memory-bank|block-memory-bank-medium
|
63423=memory-bank|block-memory-bank-medium
|
||||||
|
63422=foreshadow|block-foreshadow-medium
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 815 B |
|
Before Width: | Height: | Size: 969 KiB After Width: | Height: | Size: 949 KiB |
|
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 522 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 425 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 187 KiB |
|
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 421 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -45,7 +45,7 @@ public class GroundAI extends AIController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unit.type().canBoost && unit.canPassOn()){
|
if(unit.type().canBoost && unit.tileOn() != null && !unit.tileOn().solid()){
|
||||||
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, 0.08f);
|
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, 0.08f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class Blocks implements ContentList{
|
|||||||
coreShard, coreFoundation, coreNucleus, vault, container, unloader,
|
coreShard, coreFoundation, coreNucleus, vault, container, unloader,
|
||||||
|
|
||||||
//turrets
|
//turrets
|
||||||
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown, segment, parallax,
|
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax,
|
||||||
|
|
||||||
//units
|
//units
|
||||||
commandCenter,
|
commandCenter,
|
||||||
@@ -209,6 +209,10 @@ public class Blocks implements ContentList{
|
|||||||
isLiquid = true;
|
isLiquid = true;
|
||||||
cacheLayer = CacheLayer.slag;
|
cacheLayer = CacheLayer.slag;
|
||||||
attributes.set(Attribute.heat, 0.85f);
|
attributes.set(Attribute.heat, 0.85f);
|
||||||
|
|
||||||
|
emitLight = true;
|
||||||
|
lightRadius = 40f;
|
||||||
|
lightColor = Color.orange.cpy().a(0.38f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
stone = new Floor("stone");
|
stone = new Floor("stone");
|
||||||
@@ -243,7 +247,7 @@ public class Blocks implements ContentList{
|
|||||||
blendGroup = basalt;
|
blendGroup = basalt;
|
||||||
|
|
||||||
emitLight = true;
|
emitLight = true;
|
||||||
lightRadius = 60f;
|
lightRadius = 50f;
|
||||||
lightColor = Color.orange.cpy().a(0.3f);
|
lightColor = Color.orange.cpy().a(0.3f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -866,7 +870,8 @@ public class Blocks implements ContentList{
|
|||||||
size = 2;
|
size = 2;
|
||||||
reload = 250f;
|
reload = 250f;
|
||||||
range = 85f;
|
range = 85f;
|
||||||
healPercent = 14f;
|
healPercent = 11f;
|
||||||
|
phaseBoost = 15f;
|
||||||
health = 80 * size * size;
|
health = 80 * size * size;
|
||||||
consumes.item(Items.phasefabric).boost();
|
consumes.item(Items.phasefabric).boost();
|
||||||
}};
|
}};
|
||||||
@@ -1577,7 +1582,7 @@ public class Blocks implements ContentList{
|
|||||||
health = 250 * size * size;
|
health = 250 * size * size;
|
||||||
range = 140f;
|
range = 140f;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
consumes.power(8f);
|
consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null);
|
||||||
size = 2;
|
size = 2;
|
||||||
shootLength = 5f;
|
shootLength = 5f;
|
||||||
bulletDamage = 25f;
|
bulletDamage = 25f;
|
||||||
@@ -1660,6 +1665,48 @@ public class Blocks implements ContentList{
|
|||||||
health = 145 * size * size;
|
health = 145 * size * size;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
foreshadow = new ItemTurret("foreshadow"){{
|
||||||
|
float brange = range = 500f;
|
||||||
|
|
||||||
|
requirements(Category.turret, with(Items.copper, 1000, Items.metaglass, 600, Items.surgealloy, 300, Items.plastanium, 175, Items.thorium, 350));
|
||||||
|
ammo(
|
||||||
|
Items.surgealloy, new PointBulletType(){{
|
||||||
|
shootEffect = Fx.instShoot;
|
||||||
|
hitEffect = Fx.instHit;
|
||||||
|
smokeEffect = Fx.smokeCloud;
|
||||||
|
trailEffect = Fx.instTrail;
|
||||||
|
despawnEffect = Fx.instBomb;
|
||||||
|
trailSpacing = 20f;
|
||||||
|
damage = 1300;
|
||||||
|
tileDamageMultiplier = 0.5f;
|
||||||
|
speed = brange;
|
||||||
|
hitShake = 6f;
|
||||||
|
ammoMultiplier = 1f;
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
|
||||||
|
rotateSpeed = 2.5f;
|
||||||
|
reloadTime = 200f;
|
||||||
|
restitution = 0.2f;
|
||||||
|
ammoUseEffect = Fx.shellEjectBig;
|
||||||
|
recoilAmount = 5f;
|
||||||
|
restitution = 0.009f;
|
||||||
|
cooldown = 0.009f;
|
||||||
|
shootShake = 4f;
|
||||||
|
shots = 1;
|
||||||
|
size = 4;
|
||||||
|
shootCone = 2f;
|
||||||
|
shootSound = Sounds.shootBig;
|
||||||
|
unitSort = (u, x, y) -> -u.maxHealth;
|
||||||
|
|
||||||
|
coolantMultiplier = 0.09f;
|
||||||
|
|
||||||
|
health = 150 * size * size;
|
||||||
|
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, true);
|
||||||
|
|
||||||
|
consumes.powerCond(10f, (TurretBuild entity) -> entity.target != null || (entity.logicControlled() && entity.logicShooting));
|
||||||
|
}};
|
||||||
|
|
||||||
spectre = new ItemTurret("spectre"){{
|
spectre = new ItemTurret("spectre"){{
|
||||||
requirements(Category.turret, with(Items.copper, 900, Items.graphite, 300, Items.surgealloy, 250, Items.plastanium, 175, Items.thorium, 250));
|
requirements(Category.turret, with(Items.copper, 900, Items.graphite, 300, Items.surgealloy, 250, Items.plastanium, 175, Items.thorium, 250));
|
||||||
ammo(
|
ammo(
|
||||||
@@ -1682,7 +1729,7 @@ public class Blocks implements ContentList{
|
|||||||
shootCone = 24f;
|
shootCone = 24f;
|
||||||
shootSound = Sounds.shootBig;
|
shootSound = Sounds.shootBig;
|
||||||
|
|
||||||
health = 155 * size * size;
|
health = 160 * size * size;
|
||||||
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, true);
|
consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, true);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -455,6 +455,79 @@ public class Fx{
|
|||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
instBomb = new Effect(15f, 100f, e -> {
|
||||||
|
color(Pal.bulletYellowBack);
|
||||||
|
stroke(e.fout() * 4f);
|
||||||
|
Lines.circle(e.x, e.y, 4f + e.finpow() * 20f);
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Drawf.tri(e.x, e.y, 6f, 80f * e.fout(), i*90 + 45);
|
||||||
|
}
|
||||||
|
|
||||||
|
color();
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Drawf.tri(e.x, e.y, 3f, 30f * e.fout(), i*90 + 45);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
instTrail = new Effect(30, e -> {
|
||||||
|
for(int i = 0; i < 2; i++){
|
||||||
|
color(i == 0 ? Pal.bulletYellowBack : Pal.bulletYellow);
|
||||||
|
|
||||||
|
float m = i == 0 ? 1f : 0.5f;
|
||||||
|
|
||||||
|
float rot = e.rotation + 180f;
|
||||||
|
float w = 15f * e.fout() * m;
|
||||||
|
Drawf.tri(e.x, e.y, w, (30f + Mathf.randomSeedRange(e.id, 15f)) * m, rot);
|
||||||
|
Drawf.tri(e.x, e.y, w, 10f * m, rot + 180f);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
instShoot = new Effect(24f, e -> {
|
||||||
|
e.scaled(10f, b -> {
|
||||||
|
color(Color.white, Pal.bulletYellowBack, b.fin());
|
||||||
|
stroke(b.fout() * 3f + 0.2f);
|
||||||
|
Lines.circle(b.x, b.y, b.fin() * 50f);
|
||||||
|
});
|
||||||
|
|
||||||
|
color(Pal.bulletYellowBack);
|
||||||
|
|
||||||
|
for(int i : Mathf.signs){
|
||||||
|
Drawf.tri(e.x, e.y, 13f * e.fout(), 85f, e.rotation + 90f * i);
|
||||||
|
Drawf.tri(e.x, e.y, 13f * e.fout(), 50f, e.rotation + 20f * i);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
instHit = new Effect(20f, 200f, e -> {
|
||||||
|
color(Pal.bulletYellowBack);
|
||||||
|
|
||||||
|
for(int i = 0; i < 2; i++){
|
||||||
|
color(i == 0 ? Pal.bulletYellowBack : Pal.bulletYellow);
|
||||||
|
|
||||||
|
float m = i == 0 ? 1f : 0.5f;
|
||||||
|
|
||||||
|
for(int j = 0; j < 5; j++){
|
||||||
|
float rot = e.rotation + Mathf.randomSeedRange(e.id + j, 50f);
|
||||||
|
float w = 23f * e.fout() * m;
|
||||||
|
Drawf.tri(e.x, e.y, w, (80f + Mathf.randomSeedRange(e.id + j, 40f)) * m, rot);
|
||||||
|
Drawf.tri(e.x, e.y, w, 20f * m, rot + 180f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.scaled(10f, c -> {
|
||||||
|
color(Pal.bulletYellow);
|
||||||
|
stroke(c.fout() * 2f + 0.2f);
|
||||||
|
Lines.circle(e.x, e.y, c.fin() * 30f);
|
||||||
|
});
|
||||||
|
|
||||||
|
e.scaled(12f, c -> {
|
||||||
|
color(Pal.bulletYellowBack);
|
||||||
|
randLenVectors(e.id, 25, 5f + e.fin() * 80f, e.rotation, 60f, (x, y) -> {
|
||||||
|
Fill.square(e.x + x, e.y + y, c.fout() * 3f, 45f);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
hitLaser = new Effect(8, e -> {
|
hitLaser = new Effect(8, e -> {
|
||||||
color(Color.white, Pal.heal, e.fin());
|
color(Color.white, Pal.heal, e.fin());
|
||||||
stroke(0.5f + e.fout());
|
stroke(0.5f + e.fout());
|
||||||
@@ -1074,28 +1147,11 @@ public class Fx{
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
railHit = new Effect(18f, 200f, e -> {
|
railHit = new Effect(18f, 200f, e -> {
|
||||||
if(true){
|
color(Pal.orangeSpark);
|
||||||
color(Pal.orangeSpark);
|
|
||||||
|
|
||||||
for(int i : Mathf.signs){
|
for(int i : Mathf.signs){
|
||||||
Drawf.tri(e.x, e.y, 10f * e.fout(), 60f, e.rotation + 140f * i);
|
Drawf.tri(e.x, e.y, 10f * e.fout(), 60f, e.rotation + 140f * i);
|
||||||
}
|
|
||||||
}else{
|
|
||||||
e.scaled(7f, b -> {
|
|
||||||
color(Color.white, Color.lightGray, b.fin());
|
|
||||||
stroke(b.fout() * 2f + 0.2f);
|
|
||||||
Lines.circle(b.x, b.y, b.fin() * 28f);
|
|
||||||
});
|
|
||||||
|
|
||||||
color(Pal.orangeSpark);
|
|
||||||
float rot = e.rotation + Mathf.randomSeedRange(e.id, 20f);
|
|
||||||
float w = 9f * e.fout();
|
|
||||||
|
|
||||||
Drawf.tri(e.x, e.y, w, 100f, rot);
|
|
||||||
Drawf.tri(e.x, e.y, w, 10f, rot + 180f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
lancerLaserShoot = new Effect(21f, e -> {
|
lancerLaserShoot = new Effect(21f, e -> {
|
||||||
@@ -1109,7 +1165,7 @@ public class Fx{
|
|||||||
|
|
||||||
lancerLaserShootSmoke = new Effect(26f, e -> {
|
lancerLaserShootSmoke = new Effect(26f, e -> {
|
||||||
color(Color.white);
|
color(Color.white);
|
||||||
float length = e.data == null || !(e.data instanceof Float) ? 70f : (Float)e.data;
|
float length = !(e.data instanceof Float) ? 70f : (Float)e.data;
|
||||||
|
|
||||||
randLenVectors(e.id, 7, length, e.rotation, 0f, (x, y) -> {
|
randLenVectors(e.id, 7, length, e.rotation, 0f, (x, y) -> {
|
||||||
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ public class TechTree implements ContentList{
|
|||||||
|
|
||||||
node(Items.coal, with(Items.lead, 3000), () -> {
|
node(Items.coal, with(Items.lead, 3000), () -> {
|
||||||
node(Items.graphite, with(Items.coal, 1000), () -> {
|
node(Items.graphite, with(Items.coal, 1000), () -> {
|
||||||
|
node(illuminator, () -> {
|
||||||
|
});
|
||||||
|
|
||||||
node(graphitePress, () -> {
|
node(graphitePress, () -> {
|
||||||
node(Items.titanium, with(Items.graphite, 6000, Items.copper, 10000, Items.lead, 10000), () -> {
|
node(Items.titanium, with(Items.graphite, 6000, Items.copper, 10000, Items.lead, 10000), () -> {
|
||||||
node(pneumaticDrill, () -> {
|
node(pneumaticDrill, () -> {
|
||||||
@@ -347,8 +350,10 @@ public class TechTree implements ContentList{
|
|||||||
});
|
});
|
||||||
|
|
||||||
node(lancer, () -> {
|
node(lancer, () -> {
|
||||||
node(meltdown, () -> {
|
node(foreshadow, () -> {
|
||||||
|
node(meltdown, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
node(shockMine, () -> {
|
node(shockMine, () -> {
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ public class UnitTypes implements ContentList{
|
|||||||
continuous = true;
|
continuous = true;
|
||||||
cooldownTime = 200f;
|
cooldownTime = 200f;
|
||||||
|
|
||||||
bullet = new ContinuousLaserBulletType(17){{
|
bullet = new ContinuousLaserBulletType(20){{
|
||||||
length = 150f;
|
length = 150f;
|
||||||
hitEffect = Fx.hitMeltHeal;
|
hitEffect = Fx.hitMeltHeal;
|
||||||
drawSize = 420f;
|
drawSize = 420f;
|
||||||
@@ -430,7 +430,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
shootEffect = Fx.greenLaserChargeSmall;
|
shootEffect = Fx.greenLaserChargeSmall;
|
||||||
|
|
||||||
incendChance = 0.02f;
|
incendChance = 0.05f;
|
||||||
incendSpread = 5f;
|
incendSpread = 5f;
|
||||||
incendAmount = 1;
|
incendAmount = 1;
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ public class UnitTypes implements ContentList{
|
|||||||
mineTier = 1;
|
mineTier = 1;
|
||||||
hitSize = 29f;
|
hitSize = 29f;
|
||||||
itemCapacity = 80;
|
itemCapacity = 80;
|
||||||
health = 19000f;
|
health = 18000f;
|
||||||
buildSpeed = 1.7f;
|
buildSpeed = 1.7f;
|
||||||
armor = 9f;
|
armor = 9f;
|
||||||
landShake = 1.5f;
|
landShake = 1.5f;
|
||||||
@@ -488,8 +488,8 @@ public class UnitTypes implements ContentList{
|
|||||||
firstShotDelay = Fx.greenLaserCharge.lifetime;
|
firstShotDelay = Fx.greenLaserCharge.lifetime;
|
||||||
|
|
||||||
bullet = new LaserBulletType(){{
|
bullet = new LaserBulletType(){{
|
||||||
length = 500f;
|
length = 460f;
|
||||||
damage = 520f;
|
damage = 550f;
|
||||||
width = 75f;
|
width = 75f;
|
||||||
|
|
||||||
lifetime = 65f;
|
lifetime = 65f;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class GameState{
|
|||||||
|
|
||||||
/** @return whether the player is in a campaign and they are out of sector time */
|
/** @return whether the player is in a campaign and they are out of sector time */
|
||||||
public boolean isOutOfTime(){
|
public boolean isOutOfTime(){
|
||||||
return isCampaign() && isGame() && getSector().getTimeSpent() >= turnDuration;
|
return isCampaign() && isGame() && getSector().getTimeSpent() >= turnDuration && !net.active();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSector(){
|
public boolean hasSector(){
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
Block block = block();
|
Block block = block();
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasBuilding()){
|
||||||
build = entityprov.get().init(this, team, false, rotation);
|
build = entityprov.get().init(this, team, false, rotation);
|
||||||
build.cons = new ConsumeModule(build);
|
build.cons = new ConsumeModule(build);
|
||||||
if(block.hasItems) build.items = new ItemModule();
|
if(block.hasItems) build.items = new ItemModule();
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ public class MapGenerateDialog extends BaseDialog{
|
|||||||
public void set(Block floor, Block wall, Block ore, Team team){
|
public void set(Block floor, Block wall, Block ore, Team team){
|
||||||
this.floor = floor.id;
|
this.floor = floor.id;
|
||||||
this.block = wall.id;
|
this.block = wall.id;
|
||||||
this.ore = ore.id;
|
this.ore = floor.asFloor().isLiquid ? 0 : ore.id;
|
||||||
this.team = (byte)team.id;
|
this.team = (byte)team.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,18 @@ public class Units{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||||
|
public static Teamc bestTarget(Team team, float x, float y, float range, Boolf<Unit> unitPred, Boolf<Building> tilePred, Sortf sort){
|
||||||
|
if(team == Team.derelict) return null;
|
||||||
|
|
||||||
|
Unit unit = bestEnemy(team, x, y, range, unitPred, sort);
|
||||||
|
if(unit != null){
|
||||||
|
return unit;
|
||||||
|
}else{
|
||||||
|
return findEnemyTile(team, x, y, range, tilePred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the closest enemy of this team. Filter by predicate. */
|
/** Returns the closest enemy of this team. Filter by predicate. */
|
||||||
public static Unit closestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
public static Unit closestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate){
|
||||||
if(team == Team.derelict) return null;
|
if(team == Team.derelict) return null;
|
||||||
@@ -195,6 +207,26 @@ public class Units{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the closest enemy of this team using a custom comparison function. Filter by predicate. */
|
||||||
|
public static Unit bestEnemy(Team team, float x, float y, float range, Boolf<Unit> predicate, Sortf sort){
|
||||||
|
if(team == Team.derelict) return null;
|
||||||
|
|
||||||
|
result = null;
|
||||||
|
cdist = 0f;
|
||||||
|
|
||||||
|
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
|
||||||
|
if(e.dead() || !predicate.get(e)) return;
|
||||||
|
|
||||||
|
float dst2 = sort.cost(e, x, y);
|
||||||
|
if(dst2 < range*range && (result == null || dst2 < cdist)){
|
||||||
|
result = e;
|
||||||
|
cdist = dst2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the closest ally of this team. Filter by predicate. No range. */
|
/** Returns the closest ally of this team. Filter by predicate. No range. */
|
||||||
public static Unit closest(Team team, float x, float y, Boolf<Unit> predicate){
|
public static Unit closest(Team team, float x, float y, Boolf<Unit> predicate){
|
||||||
result = null;
|
result = null;
|
||||||
@@ -297,4 +329,7 @@ public class Units{
|
|||||||
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface Sortf{
|
||||||
|
float cost(Unit unit, float x, float y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ public abstract class BulletType extends Content{
|
|||||||
public boolean hittable = true;
|
public boolean hittable = true;
|
||||||
/** Whether this bullet can be reflected. */
|
/** Whether this bullet can be reflected. */
|
||||||
public boolean reflectable = true;
|
public boolean reflectable = true;
|
||||||
|
/** Whether to move the bullet back depending on delta to fix some delta-time realted issues.
|
||||||
|
* Do not change unless you know what you're doing. */
|
||||||
|
public boolean backMove = true;
|
||||||
/** Bullet range override. */
|
/** Bullet range override. */
|
||||||
public float range = -1f;
|
public float range = -1f;
|
||||||
|
|
||||||
@@ -212,7 +215,7 @@ public abstract class BulletType extends Content{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(instantDisappear){
|
if(instantDisappear){
|
||||||
b.time(lifetime);
|
b.time = lifetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +277,11 @@ public abstract class BulletType extends Content{
|
|||||||
bullet.owner = owner;
|
bullet.owner = owner;
|
||||||
bullet.team = team;
|
bullet.team = team;
|
||||||
bullet.vel.trns(angle, speed * velocityScl);
|
bullet.vel.trns(angle, speed * velocityScl);
|
||||||
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
|
if(backMove){
|
||||||
|
bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta);
|
||||||
|
}else{
|
||||||
|
bullet.set(x, y);
|
||||||
|
}
|
||||||
bullet.lifetime = lifetime * lifetimeScl;
|
bullet.lifetime = lifetime * lifetimeScl;
|
||||||
bullet.data = data;
|
bullet.data = data;
|
||||||
bullet.drag = drag;
|
bullet.drag = drag;
|
||||||
|
|||||||
70
core/src/mindustry/entities/bullet/PointBulletType.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package mindustry.entities.bullet;
|
||||||
|
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
public class PointBulletType extends BulletType{
|
||||||
|
private static float cdist = 0f;
|
||||||
|
private static Unit result;
|
||||||
|
|
||||||
|
public float trailSpacing = 10f;
|
||||||
|
|
||||||
|
public PointBulletType(){
|
||||||
|
scaleVelocity = true;
|
||||||
|
lifetime = 100f;
|
||||||
|
collides = false;
|
||||||
|
keepVelocity = false;
|
||||||
|
backMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Bullet b){
|
||||||
|
super.init(b);
|
||||||
|
|
||||||
|
float px = b.x + b.lifetime * b.vel.x,
|
||||||
|
py = b.y + b.lifetime * b.vel.y,
|
||||||
|
rot = b.rotation();
|
||||||
|
|
||||||
|
Geometry.iterateLine(0f, b.x, b.y, px, py, trailSpacing, (x, y) -> {
|
||||||
|
trailEffect.at(x, y, rot);
|
||||||
|
});
|
||||||
|
|
||||||
|
b.time = b.lifetime;
|
||||||
|
b.set(px, py);
|
||||||
|
|
||||||
|
//calculate hit entity
|
||||||
|
|
||||||
|
cdist = 0f;
|
||||||
|
result = null;
|
||||||
|
float range = 1f;
|
||||||
|
|
||||||
|
Units.nearbyEnemies(b.team, px - range, py - range, range*2f, range*2f, e -> {
|
||||||
|
if(e.dead()) return;
|
||||||
|
|
||||||
|
e.hitbox(Tmp.r1);
|
||||||
|
if(!Tmp.r1.contains(px, py)) return;
|
||||||
|
|
||||||
|
float dst = e.dst(px, py) - e.hitSize;
|
||||||
|
if((result == null || dst < cdist)){
|
||||||
|
result = e;
|
||||||
|
cdist = dst;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(result != null){
|
||||||
|
b.collision(result, px, py);
|
||||||
|
}else{
|
||||||
|
Building build = Vars.world.buildWorld(px, py);
|
||||||
|
if(build != null && build.team != b.team){
|
||||||
|
build.collision(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.remove();
|
||||||
|
|
||||||
|
b.vel.setZero();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1213,31 +1213,35 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sense(LAccess sensor){
|
public double sense(LAccess sensor){
|
||||||
if(sensor == LAccess.x) return x;
|
return switch(sensor){
|
||||||
if(sensor == LAccess.y) return y;
|
case x -> x;
|
||||||
if(sensor == LAccess.team) return team.id;
|
case y -> y;
|
||||||
if(sensor == LAccess.health) return health;
|
case team -> team.id;
|
||||||
if(sensor == LAccess.maxHealth) return maxHealth();
|
case health -> health;
|
||||||
if(sensor == LAccess.efficiency) return efficiency();
|
case maxHealth -> maxHealth();
|
||||||
if(sensor == LAccess.rotation) return rotation;
|
case efficiency -> efficiency();
|
||||||
if(sensor == LAccess.totalItems && items != null) return items.total();
|
case rotation -> rotation;
|
||||||
if(sensor == LAccess.totalLiquids && liquids != null) return liquids.total();
|
case totalItems -> items == null ? 0 : items.total();
|
||||||
if(sensor == LAccess.totalPower && power != null && block.consumes.hasPower()) return power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f);
|
case totalLiquids -> liquids == null ? 0 : liquids.total();
|
||||||
if(sensor == LAccess.itemCapacity) return block.itemCapacity;
|
case totalPower -> power == null || !block.consumes.hasPower() ? 0 : power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f);
|
||||||
if(sensor == LAccess.liquidCapacity) return block.liquidCapacity;
|
case itemCapacity -> block.itemCapacity;
|
||||||
if(sensor == LAccess.powerCapacity) return block.consumes.hasPower() ? block.consumes.getPower().capacity : 0f;
|
case liquidCapacity -> block.liquidCapacity;
|
||||||
if(sensor == LAccess.powerNetIn && power != null) return power.graph.getLastScaledPowerIn() * 60;
|
case powerCapacity -> block.consumes.hasPower() ? block.consumes.getPower().capacity : 0f;
|
||||||
if(sensor == LAccess.powerNetOut && power != null) return power.graph.getLastScaledPowerOut() * 60;
|
case powerNetIn -> power == null ? 0 : power.graph.getLastScaledPowerIn() * 60;
|
||||||
if(sensor == LAccess.powerNetStored && power != null) return power.graph.getLastPowerStored();
|
case powerNetOut -> power == null ? 0 : power.graph.getLastScaledPowerOut() * 60;
|
||||||
if(sensor == LAccess.powerNetCapacity && power != null) return power.graph.getLastCapacity();
|
case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored();
|
||||||
return 0;
|
case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity();
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object senseObject(LAccess sensor){
|
public Object senseObject(LAccess sensor){
|
||||||
if(sensor == LAccess.type) return block;
|
return switch(sensor){
|
||||||
|
case type -> block;
|
||||||
|
default -> noSensed;
|
||||||
|
};
|
||||||
|
|
||||||
return noSensed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
|
|||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
//trigger animation only when walking manually
|
//trigger animation only when walking manually
|
||||||
if(walked){
|
if(walked || net.client()){
|
||||||
float len = deltaLen();
|
float len = deltaLen();
|
||||||
baseRotation = Angles.moveToward(baseRotation, deltaAngle(), type().baseRotateSpeed * Mathf.clamp(len / type().speed / Time.delta) * Time.delta);
|
baseRotation = Angles.moveToward(baseRotation, deltaAngle(), type().baseRotateSpeed * Mathf.clamp(len / type().speed / Time.delta) * Time.delta);
|
||||||
walkTime += len;
|
walkTime += len;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
Building tile = payload.entity;
|
Building tile = payload.entity;
|
||||||
int tx = Vars.world.toTile(x - tile.block.offset), ty = Vars.world.toTile(y - tile.block.offset);
|
int tx = Vars.world.toTile(x - tile.block.offset), ty = Vars.world.toTile(y - tile.block.offset);
|
||||||
Tile on = Vars.world.tile(tx, ty);
|
Tile on = Vars.world.tile(tx, ty);
|
||||||
if(on != null && Build.validPlace(tile.block, tile.team, tx, ty, tile.rotation)){
|
if(on != null && Build.validPlace(tile.block, tile.team, tx, ty, tile.rotation, false)){
|
||||||
int rot = (int)((rotation + 45f) / 90f) % 4;
|
int rot = (int)((rotation + 45f) / 90f) % 4;
|
||||||
payload.place(on, rot);
|
payload.place(on, rot);
|
||||||
|
|
||||||
|
|||||||
@@ -75,24 +75,28 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sense(LAccess sensor){
|
public double sense(LAccess sensor){
|
||||||
if(sensor == LAccess.totalItems) return stack().amount;
|
return switch(sensor){
|
||||||
if(sensor == LAccess.rotation) return rotation;
|
case totalItems -> stack().amount;
|
||||||
if(sensor == LAccess.health) return health;
|
case rotation -> rotation;
|
||||||
if(sensor == LAccess.maxHealth) return maxHealth;
|
case health -> health;
|
||||||
if(sensor == LAccess.x) return x;
|
case maxHealth -> maxHealth;
|
||||||
if(sensor == LAccess.y) return y;
|
case x -> x;
|
||||||
if(sensor == LAccess.team) return team.id;
|
case y -> y;
|
||||||
if(sensor == LAccess.shooting) return isShooting() ? 1 : 0;
|
case team -> team.id;
|
||||||
if(sensor == LAccess.shootX) return aimX();
|
case shooting -> isShooting() ? 1 : 0;
|
||||||
if(sensor == LAccess.shootY) return aimY();
|
case shootX -> aimX();
|
||||||
return 0;
|
case shootY -> aimY();
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object senseObject(LAccess sensor){
|
public Object senseObject(LAccess sensor){
|
||||||
if(sensor == LAccess.type) return type;
|
return switch(sensor){
|
||||||
|
case type -> type;
|
||||||
|
default -> noSensed;
|
||||||
|
};
|
||||||
|
|
||||||
return noSensed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -417,7 +421,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
dead = true;
|
dead = true;
|
||||||
|
|
||||||
//don't waste time when the unit is already on the ground, just destroy it
|
//don't waste time when the unit is already on the ground, just destroy it
|
||||||
if(isGrounded()){
|
if(!type.flying){
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
@Import Vec2 vel;
|
@Import Vec2 vel;
|
||||||
@Import UnitType type;
|
@Import UnitType type;
|
||||||
|
|
||||||
/** minimum cursor distance from unit, fixes 'cross-eyed' shooting */
|
|
||||||
static final float minAimDst = 18f;
|
|
||||||
/** temporary weapon sequence number */
|
/** temporary weapon sequence number */
|
||||||
static int sequenceNum = 0;
|
static int sequenceNum = 0;
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
|
|||||||
/** Aim at something. This will make all mounts point at it. */
|
/** Aim at something. This will make all mounts point at it. */
|
||||||
void aim(float x, float y){
|
void aim(float x, float y){
|
||||||
Tmp.v1.set(x, y).sub(this.x, this.y);
|
Tmp.v1.set(x, y).sub(this.x, this.y);
|
||||||
if(Tmp.v1.len() < minAimDst) Tmp.v1.setLength(minAimDst);
|
if(Tmp.v1.len() < type.aimDst) Tmp.v1.setLength(type.aimDst);
|
||||||
|
|
||||||
x = Tmp.v1.x + this.x;
|
x = Tmp.v1.x + this.x;
|
||||||
y = Tmp.v1.y + this.y;
|
y = Tmp.v1.y + this.y;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package mindustry.game;
|
package mindustry.game;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
|
||||||
@@ -197,7 +199,8 @@ public class DefaultWaves{
|
|||||||
return spawns == null ? new Seq<>() : spawns;
|
return spawns == null ? new Seq<>() : spawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void generate(){
|
//TODO move elsewhere
|
||||||
|
public static Seq<SpawnGroup> generate(){
|
||||||
UnitType[][] species = {
|
UnitType[][] species = {
|
||||||
{dagger, mace, fortress, scepter, reign},
|
{dagger, mace, fortress, scepter, reign},
|
||||||
{nova, pulsar, quasar, vela, corvus},
|
{nova, pulsar, quasar, vela, corvus},
|
||||||
@@ -208,16 +211,63 @@ public class DefaultWaves{
|
|||||||
};
|
};
|
||||||
|
|
||||||
//required progression:
|
//required progression:
|
||||||
//- main progression of units, up to wave ~20
|
|
||||||
//- changes from
|
|
||||||
//- extra periodic patterns
|
//- extra periodic patterns
|
||||||
|
|
||||||
|
Seq<SpawnGroup> out = new Seq<>();
|
||||||
|
|
||||||
//max reasonable wave, after which everything gets boring
|
//max reasonable wave, after which everything gets boring
|
||||||
int cap = 300;
|
int cap = 400;
|
||||||
for(int i = 0; i < cap; i++){
|
|
||||||
|
|
||||||
|
//main sequence
|
||||||
|
float shieldStart = 30, shieldsPerWave = 12;
|
||||||
|
UnitType[] curSpecies = Structs.random(species);
|
||||||
|
int curTier = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < cap;){
|
||||||
|
int f = i;
|
||||||
|
int next = Mathf.random(15, 25);
|
||||||
|
|
||||||
|
float shieldAmount = Math.max((i - shieldStart) * shieldsPerWave, 0);
|
||||||
|
|
||||||
|
//main progression
|
||||||
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
|
unitAmount = f == 0 ? 1 : 10;
|
||||||
|
begin = f;
|
||||||
|
end = f + next >= cap ? never : f + next;
|
||||||
|
max = 16;
|
||||||
|
unitScaling = Mathf.random(1f, 2f);
|
||||||
|
shields = shieldAmount;
|
||||||
|
shieldScaling = shieldsPerWave;
|
||||||
|
}});
|
||||||
|
|
||||||
|
//extra progression that tails out, blends in
|
||||||
|
out.add(new SpawnGroup(curSpecies[Math.min(curTier, curSpecies.length - 1)]){{
|
||||||
|
unitAmount = 6;
|
||||||
|
begin = f + next;
|
||||||
|
end = f + next + Mathf.random(8, 12);
|
||||||
|
max = 10;
|
||||||
|
unitScaling = Mathf.random(2f);
|
||||||
|
spacing = Mathf.random(2, 3);
|
||||||
|
shields = shieldAmount;
|
||||||
|
shieldScaling = shieldsPerWave;
|
||||||
|
}});
|
||||||
|
|
||||||
|
i += next;
|
||||||
|
if(curTier < 3 || Mathf.chance(0.2)){
|
||||||
|
curTier ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do not spawn bosses
|
||||||
|
curTier = Math.min(curTier, 3);
|
||||||
|
|
||||||
|
//small chance to switch species
|
||||||
|
if(Mathf.chance(0.2)){
|
||||||
|
curSpecies = Structs.random(species);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class BlockRenderer implements Disposable{
|
|||||||
private FrameBuffer dark = new FrameBuffer();
|
private FrameBuffer dark = new FrameBuffer();
|
||||||
private Seq<Building> outArray2 = new Seq<>();
|
private Seq<Building> outArray2 = new Seq<>();
|
||||||
private Seq<Tile> shadowEvents = new Seq<>();
|
private Seq<Tile> shadowEvents = new Seq<>();
|
||||||
private IntSet processedEntities = new IntSet();
|
private IntSet processedEntities = new IntSet(), processedLinks = new IntSet();
|
||||||
private boolean displayStatus = false;
|
private boolean displayStatus = false;
|
||||||
|
|
||||||
public BlockRenderer(){
|
public BlockRenderer(){
|
||||||
@@ -180,6 +180,7 @@ public class BlockRenderer implements Disposable{
|
|||||||
tileview.clear();
|
tileview.clear();
|
||||||
lightview.clear();
|
lightview.clear();
|
||||||
processedEntities.clear();
|
processedEntities.clear();
|
||||||
|
processedLinks.clear();
|
||||||
|
|
||||||
int minx = Math.max(avgx - rangex - expandr, 0);
|
int minx = Math.max(avgx - rangex - expandr, 0);
|
||||||
int miny = Math.max(avgy - rangey - expandr, 0);
|
int miny = Math.max(avgy - rangey - expandr, 0);
|
||||||
@@ -196,10 +197,15 @@ public class BlockRenderer implements Disposable{
|
|||||||
tile = tile.build.tile;
|
tile = tile.build.tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.build == null || !processedEntities.contains(tile.build.id()))){
|
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.build == null || !processedEntities.contains(tile.build.id))){
|
||||||
if(block.expanded || !expanded){
|
if(block.expanded || !expanded){
|
||||||
tileview.add(tile);
|
if(tile.build == null || processedLinks.add(tile.build.id)){
|
||||||
if(tile.build != null) processedEntities.add(tile.build.id());
|
tileview.add(tile);
|
||||||
|
if(tile.build != null){
|
||||||
|
processedEntities.add(tile.build.id);
|
||||||
|
processedLinks.add(tile.build.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//lights are drawn even in the expanded range
|
//lights are drawn even in the expanded range
|
||||||
@@ -209,7 +215,7 @@ public class BlockRenderer implements Disposable{
|
|||||||
|
|
||||||
if(tile.build != null && tile.build.power != null && tile.build.power.links.size > 0){
|
if(tile.build != null && tile.build.power != null && tile.build.power.links.size > 0){
|
||||||
for(Building other : tile.build.getPowerConnections(outArray2)){
|
for(Building other : tile.build.getPowerConnections(outArray2)){
|
||||||
if(other.block instanceof PowerNode){ //TODO need a generic way to render connections!
|
if(other.block instanceof PowerNode && processedLinks.add(other.id)){ //TODO need a generic way to render connections!
|
||||||
tileview.add(other.tile);
|
tileview.add(other.tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
//TODO find out number with best performance
|
//TODO find out number with best performance
|
||||||
private static final int chunksize = mobile ? 16 : 32;
|
private static final int chunksize = mobile ? 16 : 32;
|
||||||
|
|
||||||
private Chunk[][] cache;
|
private int[][][] cache;
|
||||||
private MultiCacheBatch cbatch;
|
private MultiCacheBatch cbatch;
|
||||||
private IntSet drawnLayerSet = new IntSet();
|
private IntSet drawnLayerSet = new IntSet();
|
||||||
private IntSet recacheSet = new IntSet();
|
private IntSet recacheSet = new IntSet();
|
||||||
@@ -63,11 +63,11 @@ public class FloorRenderer implements Disposable{
|
|||||||
if(!Structs.inBounds(worldx, worldy, cache))
|
if(!Structs.inBounds(worldx, worldy, cache))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Chunk chunk = cache[worldx][worldy];
|
int[] chunk = cache[worldx][worldy];
|
||||||
|
|
||||||
//loop through all layers, and add layer index if it exists
|
//loop through all layers, and add layer index if it exists
|
||||||
for(int i = 0; i < layers; i++){
|
for(int i = 0; i < layers; i++){
|
||||||
if(chunk.caches[i] != -1 && i != CacheLayer.walls.ordinal()){
|
if(chunk[i] != -1 && i != CacheLayer.walls.ordinal()){
|
||||||
drawnLayerSet.add(i);
|
drawnLayerSet.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,9 +154,9 @@ public class FloorRenderer implements Disposable{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk chunk = cache[worldx][worldy];
|
int[] chunk = cache[worldx][worldy];
|
||||||
if(chunk.caches[layer.ordinal()] == -1) continue;
|
if(chunk[layer.ordinal()] == -1) continue;
|
||||||
cbatch.drawCache(chunk.caches[layer.ordinal()]);
|
cbatch.drawCache(chunk[layer.ordinal()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
|
|
||||||
private void cacheChunk(int cx, int cy){
|
private void cacheChunk(int cx, int cy){
|
||||||
used.clear();
|
used.clear();
|
||||||
Chunk chunk = cache[cx][cy];
|
int[] chunk = cache[cx][cy];
|
||||||
|
|
||||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize && tilex < world.width(); tilex++){
|
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize && tilex < world.width(); tilex++){
|
||||||
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize && tiley < world.height(); tiley++){
|
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize && tiley < world.height(); tiley++){
|
||||||
@@ -184,15 +184,15 @@ public class FloorRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cacheChunkLayer(int cx, int cy, Chunk chunk, CacheLayer layer){
|
private void cacheChunkLayer(int cx, int cy, int[] chunk, CacheLayer layer){
|
||||||
Batch current = Core.batch;
|
Batch current = Core.batch;
|
||||||
Core.batch = cbatch;
|
Core.batch = cbatch;
|
||||||
|
|
||||||
//begin a new cache
|
//begin a new cache
|
||||||
if(chunk.caches[layer.ordinal()] == -1){
|
if(chunk[layer.ordinal()] == -1){
|
||||||
cbatch.beginCache();
|
cbatch.beginCache();
|
||||||
}else{
|
}else{
|
||||||
cbatch.beginCache(chunk.caches[layer.ordinal()]);
|
cbatch.beginCache(chunk[layer.ordinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
||||||
@@ -218,7 +218,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
|
|
||||||
Core.batch = current;
|
Core.batch = current;
|
||||||
cbatch.reserve(layer.capacity * chunksize * chunksize);
|
cbatch.reserve(layer.capacity * chunksize * chunksize);
|
||||||
chunk.caches[layer.ordinal()] = cbatch.endCache();
|
chunk[layer.ordinal()] = cbatch.endCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearTiles(){
|
public void clearTiles(){
|
||||||
@@ -227,15 +227,14 @@ public class FloorRenderer implements Disposable{
|
|||||||
recacheSet.clear();
|
recacheSet.clear();
|
||||||
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
||||||
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
||||||
cache = new Chunk[chunksx][chunksy];
|
cache = new int[chunksx][chunksy][CacheLayer.all.length];
|
||||||
cbatch = new MultiCacheBatch(chunksize * chunksize * 8);
|
cbatch = new MultiCacheBatch(chunksize * chunksize * 9);
|
||||||
|
|
||||||
Time.mark();
|
Time.mark();
|
||||||
|
|
||||||
for(int x = 0; x < chunksx; x++){
|
for(int x = 0; x < chunksx; x++){
|
||||||
for(int y = 0; y < chunksy; y++){
|
for(int y = 0; y < chunksy; y++){
|
||||||
cache[x][y] = new Chunk();
|
Arrays.fill(cache[x][y], -1);
|
||||||
Arrays.fill(cache[x][y].caches, -1);
|
|
||||||
|
|
||||||
cacheChunk(x, y);
|
cacheChunk(x, y);
|
||||||
}
|
}
|
||||||
@@ -251,13 +250,4 @@ public class FloorRenderer implements Disposable{
|
|||||||
cbatch = null;
|
cbatch = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Chunk{
|
|
||||||
/** Maps cache layer ID to cache ID in the batch.
|
|
||||||
* -1 means that this cache is unoccupied. */
|
|
||||||
int[] caches = new int[CacheLayer.all.length];
|
|
||||||
|
|
||||||
Chunk(){
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
|
|
||||||
if(hadEntity){
|
if(hadEntity){
|
||||||
if(isCenter){ //only read entity for center blocks
|
if(isCenter){ //only read entity for center blocks
|
||||||
if(block.hasEntity()){
|
if(block.hasBuilding()){
|
||||||
try{
|
try{
|
||||||
readChunk(stream, true, in -> {
|
readChunk(stream, true, in -> {
|
||||||
byte revision = in.readByte();
|
byte revision = in.readByte();
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public abstract class LegacySaveVersion extends SaveVersion{
|
|||||||
tile.setBlock(block);
|
tile.setBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasBuilding()){
|
||||||
try{
|
try{
|
||||||
readChunk(stream, true, in -> {
|
readChunk(stream, true, in -> {
|
||||||
byte version = in.readByte();
|
byte version = in.readByte();
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ public enum ConditionOp{
|
|||||||
lessThan("<", (a, b) -> a < b),
|
lessThan("<", (a, b) -> a < b),
|
||||||
lessThanEq("<=", (a, b) -> a <= b),
|
lessThanEq("<=", (a, b) -> a <= b),
|
||||||
greaterThan(">", (a, b) -> a > b),
|
greaterThan(">", (a, b) -> a > b),
|
||||||
greaterThanEq(">=", (a, b) -> a >= b);
|
greaterThanEq(">=", (a, b) -> a >= b),
|
||||||
|
always("always", (a, b) -> true);
|
||||||
|
|
||||||
public static final ConditionOp[] all = values();
|
public static final ConditionOp[] all = values();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
|
import arc.graphics.*;
|
||||||
import arc.scene.style.*;
|
import arc.scene.style.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
@@ -633,6 +634,8 @@ public class LStatements{
|
|||||||
|
|
||||||
@RegisterStatement("jump")
|
@RegisterStatement("jump")
|
||||||
public static class JumpStatement extends LStatement{
|
public static class JumpStatement extends LStatement{
|
||||||
|
private static Color last = new Color();
|
||||||
|
|
||||||
public transient StatementElem dest;
|
public transient StatementElem dest;
|
||||||
|
|
||||||
public int destIndex;
|
public int destIndex;
|
||||||
@@ -644,19 +647,30 @@ public class LStatements{
|
|||||||
public void build(Table table){
|
public void build(Table table){
|
||||||
table.add("if ").padLeft(4);
|
table.add("if ").padLeft(4);
|
||||||
|
|
||||||
field(table, value, str -> value = str);
|
last = table.color;
|
||||||
|
table.table(this::rebuild);
|
||||||
table.button(b -> {
|
|
||||||
b.label(() -> op.symbol);
|
|
||||||
b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> op = o));
|
|
||||||
}, Styles.logict, () -> {}).size(48f, 40f).pad(4f).color(table.color);
|
|
||||||
|
|
||||||
field(table, compare, str -> compare = str);
|
|
||||||
|
|
||||||
table.add().growX();
|
table.add().growX();
|
||||||
table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8);
|
table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebuild(Table table){
|
||||||
|
table.clearChildren();
|
||||||
|
table.setColor(last);
|
||||||
|
|
||||||
|
if(op != ConditionOp.always) field(table, value, str -> value = str);
|
||||||
|
|
||||||
|
table.button(b -> {
|
||||||
|
b.label(() -> op.symbol);
|
||||||
|
b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> {
|
||||||
|
op = o;
|
||||||
|
rebuild(table);
|
||||||
|
}));
|
||||||
|
}, Styles.logict, () -> {}).size(op == ConditionOp.always ? 80f : 48f, 40f).pad(4f).color(table.color);
|
||||||
|
|
||||||
|
if(op != ConditionOp.always) field(table, compare, str -> compare = str);
|
||||||
|
}
|
||||||
|
|
||||||
//elements need separate conversion logic
|
//elements need separate conversion logic
|
||||||
@Override
|
@Override
|
||||||
public void setupUI(){
|
public void setupUI(){
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ import static mindustry.Vars.net;
|
|||||||
public class CrashSender{
|
public class CrashSender{
|
||||||
|
|
||||||
public static String createReport(String error){
|
public static String createReport(String error){
|
||||||
String report = "Oh no, Mindustry crashed!\n";
|
String report = "Mindustry has crashed. How unforunate.\n";
|
||||||
if(mods.list().size == 0){
|
if(mods.list().size == 0 && Version.build != -1){
|
||||||
report += "Please report this at " + Vars.reportIssueURL + "\n\n";
|
report += "Report this at " + Vars.reportIssueURL + "\n\n";
|
||||||
}
|
}
|
||||||
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
|
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
|
||||||
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
||||||
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
||||||
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
||||||
+ mods.list().size + " Mods: " + (mods.list().isEmpty() ? "none" : mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
+ mods.list().size + " Mods" + (mods.list().isEmpty() ? "" : ": " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
||||||
+ "\n\n" + error;
|
+ "\n\n" + error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
public boolean destructibleWreck = true;
|
public boolean destructibleWreck = true;
|
||||||
public float groundLayer = Layer.groundUnit;
|
public float groundLayer = Layer.groundUnit;
|
||||||
public float payloadCapacity = 8;
|
public float payloadCapacity = 8;
|
||||||
|
public float aimDst = -1f;
|
||||||
public int commandLimit = 24;
|
public int commandLimit = 24;
|
||||||
public float visualElevation = -1f;
|
public float visualElevation = -1f;
|
||||||
public boolean allowLegStep = false;
|
public boolean allowLegStep = false;
|
||||||
@@ -218,6 +219,10 @@ public class UnitType extends UnlockableContent{
|
|||||||
mechStride = 4f + (hitSize -8f)/2.1f;
|
mechStride = 4f + (hitSize -8f)/2.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(aimDst < 0){
|
||||||
|
aimDst = weapons.contains(w -> !w.rotate) ? hitSize * 2f : hitSize / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
if(mechStepShake < 0){
|
if(mechStepShake < 0){
|
||||||
mechStepShake = Mathf.round((hitSize - 11f) / 9f);
|
mechStepShake = Mathf.round((hitSize - 11f) / 9f);
|
||||||
mechStepParticles = hitSize > 15f;
|
mechStepParticles = hitSize > 15f;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.util.*;
|
|||||||
|
|
||||||
public class FileChooser extends BaseDialog{
|
public class FileChooser extends BaseDialog{
|
||||||
private static final Fi homeDirectory = Core.files.absolute(Core.files.getExternalStoragePath());
|
private static final Fi homeDirectory = Core.files.absolute(Core.files.getExternalStoragePath());
|
||||||
static Fi lastDirectory = homeDirectory;
|
static Fi lastDirectory = Core.files.absolute(Core.settings.getString("lastDirectory", homeDirectory.absolutePath()));
|
||||||
|
|
||||||
private Table files;
|
private Table files;
|
||||||
Fi directory = lastDirectory;
|
Fi directory = lastDirectory;
|
||||||
@@ -108,7 +108,7 @@ public class FileChooser extends BaseDialog{
|
|||||||
ImageButton home = new ImageButton(Icon.home);
|
ImageButton home = new ImageButton(Icon.home);
|
||||||
home.clicked(() -> {
|
home.clicked(() -> {
|
||||||
directory = homeDirectory;
|
directory = homeDirectory;
|
||||||
lastDirectory = directory;
|
setLastDirectory(directory);
|
||||||
updateFiles(true);
|
updateFiles(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ public class FileChooser extends BaseDialog{
|
|||||||
TextButton upbutton = new TextButton(".." + directory.toString(), Styles.clearTogglet);
|
TextButton upbutton = new TextButton(".." + directory.toString(), Styles.clearTogglet);
|
||||||
upbutton.clicked(() -> {
|
upbutton.clicked(() -> {
|
||||||
directory = directory.parent();
|
directory = directory.parent();
|
||||||
lastDirectory = directory;
|
setLastDirectory(directory);
|
||||||
updateFiles(true);
|
updateFiles(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ public class FileChooser extends BaseDialog{
|
|||||||
updateFileFieldStatus();
|
updateFileFieldStatus();
|
||||||
}else{
|
}else{
|
||||||
directory = directory.child(filename);
|
directory = directory.child(filename);
|
||||||
lastDirectory = directory;
|
setLastDirectory(directory);
|
||||||
updateFiles(true);
|
updateFiles(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -242,6 +242,11 @@ public class FileChooser extends BaseDialog{
|
|||||||
if(open) filefield.clearText();
|
if(open) filefield.clearText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setLastDirectory(Fi directory){
|
||||||
|
lastDirectory = directory;
|
||||||
|
Core.settings.put("lastDirectory", directory.absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
private String shorten(String string){
|
private String shorten(String string){
|
||||||
int max = 30;
|
int max = 30;
|
||||||
if(string.length() <= max){
|
if(string.length() <= max){
|
||||||
@@ -269,14 +274,14 @@ public class FileChooser extends BaseDialog{
|
|||||||
if(!canBack()) return;
|
if(!canBack()) return;
|
||||||
index--;
|
index--;
|
||||||
directory = history.get(index - 1);
|
directory = history.get(index - 1);
|
||||||
lastDirectory = directory;
|
setLastDirectory(directory);
|
||||||
updateFiles(false);
|
updateFiles(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forward(){
|
public void forward(){
|
||||||
if(!canForward()) return;
|
if(!canForward()) return;
|
||||||
directory = history.get(index);
|
directory = history.get(index);
|
||||||
lastDirectory = directory;
|
setLastDirectory(directory);
|
||||||
index++;
|
index++;
|
||||||
updateFiles(false);
|
updateFiles(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -703,7 +703,7 @@ public class HudFragment extends Fragment{
|
|||||||
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
|
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
|
||||||
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
|
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
|
||||||
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
|
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
|
||||||
b.color.set(player.displayAmmo() ? player.dead() ? Pal.ammo : player.unit().type().ammoType.color : Pal.health);
|
b.color.set(player.displayAmmo() ? player.dead() || player.unit() instanceof BlockUnitc ? Pal.ammo : player.unit().type().ammoType.color : Pal.health);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.getChildren().get(1).toFront();
|
t.getChildren().get(1).toFront();
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ public class Block extends UnlockableContent{
|
|||||||
public @Load("@-team") TextureRegion teamRegion;
|
public @Load("@-team") TextureRegion teamRegion;
|
||||||
public TextureRegion[] teamRegions;
|
public TextureRegion[] teamRegions;
|
||||||
|
|
||||||
|
//TODO make this not static
|
||||||
public static TextureRegion[][] cracks;
|
public static TextureRegion[][] cracks;
|
||||||
protected static final Seq<Tile> tempTiles = new Seq<>();
|
protected static final Seq<Tile> tempTiles = new Seq<>();
|
||||||
protected static final Seq<Building> tempTileEnts = new Seq<>();
|
protected static final Seq<Building> tempTileEnts = new Seq<>();
|
||||||
@@ -499,7 +500,7 @@ public class Block extends UnlockableContent{
|
|||||||
return variantRegions;
|
return variantRegions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEntity(){
|
public boolean hasBuilding(){
|
||||||
return destructible || update;
|
return destructible || update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,13 @@ public class Build{
|
|||||||
|
|
||||||
/** Returns whether a tile can be placed at this location by this team. */
|
/** Returns whether a tile can be placed at this location by this team. */
|
||||||
public static boolean validPlace(Block type, Team team, int x, int y, int rotation){
|
public static boolean validPlace(Block type, Team team, int x, int y, int rotation){
|
||||||
|
return validPlace(type, team, x, y, rotation, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether a tile can be placed at this location by this team. */
|
||||||
|
public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
|
||||||
//the wave team can build whatever they want as long as it's visible - banned blocks are not applicable
|
//the wave team can build whatever they want as long as it's visible - banned blocks are not applicable
|
||||||
if(type == null || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible()))){
|
if(type == null || (checkVisible && (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible())))){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class CachedTile extends Tile{
|
|||||||
|
|
||||||
Block block = block();
|
Block block = block();
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasBuilding()){
|
||||||
Building n = entityprov.get();
|
Building n = entityprov.get();
|
||||||
n.cons(new ConsumeModule(build));
|
n.cons(new ConsumeModule(build));
|
||||||
n.tile(this);
|
n.tile(this);
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block.hasEntity()){
|
if(block.hasBuilding()){
|
||||||
build = entityprov.get().init(this, team, block.update && !state.isEditor(), rotation);
|
build = entityprov.get().init(this, team, block.update && !state.isEditor(), rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,11 @@ public class LaunchPad extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
|
if(!state.isCampaign()){
|
||||||
|
deselect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
table.button(Icon.upOpen, Styles.clearTransi, () -> {
|
||||||
ui.planet.showSelect(state.rules.sector, other -> state.secinfo.destination = other);
|
ui.planet.showSelect(state.rules.sector, other -> state.secinfo.destination = other);
|
||||||
deselect();
|
deselect();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import arc.util.io.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.entities.Units.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -67,6 +68,7 @@ public abstract class Turret extends Block{
|
|||||||
public float coolantMultiplier = 5f;
|
public float coolantMultiplier = 5f;
|
||||||
/** Effect displayed when coolant is used. */
|
/** Effect displayed when coolant is used. */
|
||||||
public Effect coolEffect = Fx.fuelburn;
|
public Effect coolEffect = Fx.fuelburn;
|
||||||
|
public Sortf unitSort = Unit::dst2;
|
||||||
|
|
||||||
protected Vec2 tr = new Vec2();
|
protected Vec2 tr = new Vec2();
|
||||||
protected Vec2 tr2 = new Vec2();
|
protected Vec2 tr2 = new Vec2();
|
||||||
@@ -306,9 +308,9 @@ public abstract class Turret extends Block{
|
|||||||
|
|
||||||
protected void findTarget(){
|
protected void findTarget(){
|
||||||
if(targetAir && !targetGround){
|
if(targetAir && !targetGround){
|
||||||
target = Units.closestEnemy(team, x, y, range, e -> !e.dead() && !e.isGrounded());
|
target = Units.bestEnemy(team, x, y, range, e -> !e.dead() && !e.isGrounded(), unitSort);
|
||||||
}else{
|
}else{
|
||||||
target = Units.closestTarget(team, x, y, range, e -> !e.dead() && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround));
|
target = Units.bestTarget(team, x, y, range, e -> !e.dead() && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround), b -> true, unitSort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +399,7 @@ public abstract class Turret extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void bullet(BulletType type, float angle){
|
protected void bullet(BulletType type, float angle){
|
||||||
float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x, y, targetPos.x, targetPos.y) / type.range(), minRange / type.range(), range / type.range()) : 1f;
|
float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x + tr.x, y + tr.y, targetPos.x, targetPos.y) / type.range(), minRange / type.range(), range / type.range()) : 1f;
|
||||||
|
|
||||||
type.create(this, team, x + tr.x, y + tr.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl);
|
type.create(this, team, x + tr.x, y + tr.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
public PowerNode(String name){
|
public PowerNode(String name){
|
||||||
super(name);
|
super(name);
|
||||||
expanded = true;
|
|
||||||
configurable = true;
|
configurable = true;
|
||||||
consumesPower = false;
|
consumesPower = false;
|
||||||
outputsPower = false;
|
outputsPower = false;
|
||||||
@@ -392,7 +391,7 @@ public class PowerNode extends PowerBlock{
|
|||||||
|
|
||||||
if(!linkValid(this, link)) continue;
|
if(!linkValid(this, link)) continue;
|
||||||
|
|
||||||
if(link.block instanceof PowerNode && !(link.pos() < tile.pos())) continue;
|
if(link.block instanceof PowerNode && link.id >= id) continue;
|
||||||
|
|
||||||
drawLaser(team, x, y, link.x, link.y, size, link.block.size);
|
drawLaser(team, x, y, link.x, link.y, size, link.block.size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
CoreBuild core = team.core();
|
CoreBuild core = team.core();
|
||||||
//must have all requirements
|
//must have all requirements
|
||||||
if(core == null || (!state.rules.infiniteResources && !core.items.has(requirements))) return false;
|
if(core == null || (!state.rules.infiniteResources && !core.items.has(requirements))) return false;
|
||||||
return canReplace(tile.block());
|
return tile.block() instanceof CoreBlock && size > tile.block().size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ task run(dependsOn: classes, type: JavaExec){
|
|||||||
jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true")
|
jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jvmArgs += "-XX:+ShowCodeDetailsInExceptionMessages"
|
||||||
|
|
||||||
/*spriteHashFile.parentFile.mkdirs()
|
/*spriteHashFile.parentFile.mkdirs()
|
||||||
String spriteHash = hashDirectory()
|
String spriteHash = hashDirectory()
|
||||||
if(spriteHashFile.exists() && spriteHashFile.text != spriteHash){
|
if(spriteHashFile.exists() && spriteHashFile.text != spriteHash){
|
||||||
|
|||||||
9
fastlane/metadata/android/en-US/changelogs/29664.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
This is a small update. Not much new content, mostly bugfixes.
|
||||||
|
The next planned update will focus on the campaign, and will likely take much longer.
|
||||||
|
|
||||||
|
- Bugfixes
|
||||||
|
- Added team color for command center (Contributed by Voz-Duh)
|
||||||
|
- Cleaned up certain sprites to match V6 style (Partially contributed by Voz-Duh)
|
||||||
|
- Added support for Java-based mods on Android (mostly undocumented for now)
|
||||||
|
- Added 2x2 high capacity memory bank for logic processors
|
||||||
|
- Balancing
|
||||||