diff --git a/core/src/mindustry/async/PhysicsProcess.java b/core/src/mindustry/async/PhysicsProcess.java index 5928b3f2c3..52f4bdcafc 100644 --- a/core/src/mindustry/async/PhysicsProcess.java +++ b/core/src/mindustry/async/PhysicsProcess.java @@ -150,14 +150,17 @@ public class PhysicsProcess implements AsyncProcess{ trees[i].clear(); } - for(int i = 0; i < bodies.size; i++){ - PhysicsBody body = bodies.items[i]; + var bodyItems = bodies.items; + int bodySize = bodies.size; + + for(int i = 0; i < bodySize; i++){ + PhysicsBody body = bodyItems[i]; body.collided = false; trees[body.layer].insert(body); } - for(int i = 0; i < bodies.size; i++){ - PhysicsBody body = bodies.items[i]; + for(int i = 0; i < bodySize; i++){ + PhysicsBody body = bodyItems[i]; //for clients, the only body that collides is the local one; all other physics simulations are handled by the server. if(!body.local) continue; @@ -166,9 +169,11 @@ public class PhysicsProcess implements AsyncProcess{ seq.size = 0; trees[body.layer].intersect(rect, seq); + int size = seq.size; + var items = seq.items; - for(int j = 0; j < seq.size; j++){ - PhysicsBody other = seq.items[j]; + for(int j = 0; j < size; j++){ + PhysicsBody other = items[j]; if(other == body || other.collided) continue; diff --git a/core/src/mindustry/entities/pattern/ShotPattern.java b/core/src/mindustry/entities/pattern/ShotPattern.java index d9be232034..01f183e527 100644 --- a/core/src/mindustry/entities/pattern/ShotPattern.java +++ b/core/src/mindustry/entities/pattern/ShotPattern.java @@ -6,7 +6,7 @@ import arc.math.geom.*; //TODO public class ShotPattern{ - public void shoot(Cons positionSetter, Cons positionHandler){ + public void shoot(float x, float y, Cons positionHandler){ } } diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 8ea1a7c4fe..d22a39ae20 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -1299,6 +1299,18 @@ public class LExecutor{ } } case ambientLight -> state.rules.ambientLight.fromDouble(exec.num(value)); + case unitBuildSpeed, unitDamage, blockHealth, blockDamage, buildSpeed -> { + if(exec.obj(p1) instanceof Team team){ + float num = exec.numf(value); + switch(rule){ + case buildSpeed -> team.rules().buildSpeedMultiplier = Mathf.clamp(num, 0.001f, 50f); + case unitBuildSpeed -> team.rules().unitBuildSpeedMultiplier = Mathf.clamp(num, 0f, 50f); + case unitDamage -> team.rules().unitDamageMultiplier = Math.max(num, 0f); + case blockHealth -> team.rules().blockHealthMultiplier = Math.max(num, 0.001f); + case blockDamage -> team.rules().blockDamageMultiplier = Math.max(num, 0f); + } + } + } } } } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 6472ece84f..0488e68444 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -1237,13 +1237,20 @@ public class LStatements{ @RegisterStatement("setrule") public static class SetRuleStatement extends LStatement{ public LogicRule rule = LogicRule.waveSpacing; - public String value = "100", p1 = "0", p2 = "0", p3 = "100", p4 = "100"; + public String value = "10", p1 = "0", p2 = "0", p3 = "100", p4 = "100"; @Override public void build(Table table){ rebuild(table); } + /* + unitBuildSpeed, + unitDamage, + blockHealth, + blockDamage + */ + void rebuild(Table table){ table.clearChildren(); @@ -1253,19 +1260,31 @@ public class LStatements{ rule = o; rebuild(table); }, 2, c -> c.width(150f))); - }, Styles.logict, () -> {}).size(160f, 40f).pad(4f).color(table.color); - - table.add(" = "); + }, Styles.logict, () -> {}).size(160f, 40f).margin(5f).pad(4f).color(table.color); switch(rule){ case mapArea -> { + table.add(" = "); + fields(table, "x", p1, s -> p1 = s); fields(table, "y", p2, s -> p2 = s); row(table); fields(table, "w", p3, s -> p3 = s); fields(table, "h", p4, s -> p4 = s); } + case buildSpeed, unitBuildSpeed, unitDamage, blockHealth, blockDamage -> { + if(p1.equals("0")){ + p1 = "@sharded"; + } + + fields(table, "of", p1, s -> p1 = s); + table.add(" = "); + row(table); + field(table, value, s -> value = s); + } default -> { + table.add(" = "); + field(table, value, s -> value = s); } } diff --git a/core/src/mindustry/logic/LogicRule.java b/core/src/mindustry/logic/LogicRule.java index 05ba622c34..62ec3795a7 100644 --- a/core/src/mindustry/logic/LogicRule.java +++ b/core/src/mindustry/logic/LogicRule.java @@ -11,7 +11,14 @@ public enum LogicRule{ unitCap, mapArea, lighting, - ambientLight; + ambientLight, + + //team specific + buildSpeed, + unitBuildSpeed, + unitDamage, + blockHealth, + blockDamage; public static final LogicRule[] all = values(); } diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index 5bb0dc808d..f5f5cb4049 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -175,7 +175,7 @@ public class CustomRulesDialog extends BaseDialog{ check("@rules.unitcapvariable", b -> rules.unitCapVariable = b, () -> rules.unitCapVariable); numberi("@rules.unitcap", f -> rules.unitCap = f, () -> rules.unitCap, -999, 999); number("@rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); - number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.001f, 50f); + number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0f, 50f); main.button("@bannedunits", () -> showBanned("@bannedunits", ContentType.unit, rules.bannedUnits, u -> !u.isHidden())).left().width(300f); main.row(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java index 5cbf080141..c692178f75 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java @@ -115,8 +115,8 @@ public class ContinuousTurret extends Turret{ } @Override - protected void bullet(BulletType type, float angle){ - bullet = type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle); + protected void handleBullet(@Nullable Bullet bullet){ + this.bullet = bullet; } @Override diff --git a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java index 81a5981762..bad5528986 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -108,8 +108,8 @@ public class LaserTurret extends PowerTurret{ } @Override - protected void bullet(BulletType type, float angle){ - bullet = type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle); + protected void handleBullet(@Nullable Bullet bullet){ + this.bullet = bullet; bulletLife = shootDuration; } diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 45e464b76f..2259264cbd 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -178,7 +178,7 @@ public class Turret extends ReloadTurret{ } public class TurretBuild extends ReloadTurretBuild implements ControlBlock{ - //TODO storing these as instance variables is bad design, but it's probably too late to change everything + //TODO storing these as instance variables is horrible design /** Turret sprite offset, based on recoil. Updated every frame. */ public Vec2 recoilOffset = new Vec2(); /** Turret bullet position offset. Updated every frame. */ @@ -559,21 +559,18 @@ public class Turret extends ReloadTurret{ } protected void bullet(BulletType type, float angle){ - float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x + bulletOffset.x, y + bulletOffset.y, targetPos.x, targetPos.y) / type.range, minRange / type.range, range() / type.range) : 1f; + float bulletX = x + bulletOffset.x, bulletY = y + bulletOffset.y; + float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(bulletX, bulletY, targetPos.x, targetPos.y) / type.range, minRange / type.range, range() / type.range) : 1f; - type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl); - effects(); - } + handleBullet(type.create(this, team, bulletX, bulletY, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl)); - protected void effects(){ - var bullet = peekAmmo(); //TODO "shoot" and "smoke" should just be MultiEffects there's no reason to have them separate - Effect fshootEffect = shootEffect == Fx.none ? bullet.shootEffect : shootEffect; - Effect fsmokeEffect = smokeEffect == Fx.none ? bullet.smokeEffect : smokeEffect; + Effect fshootEffect = shootEffect == Fx.none ? type.shootEffect : shootEffect; + Effect fsmokeEffect = smokeEffect == Fx.none ? type.smokeEffect : smokeEffect; - fshootEffect.at(x + bulletOffset.x, y + bulletOffset.y, rotation, bullet.hitColor); - fsmokeEffect.at(x + bulletOffset.x, y + bulletOffset.y, rotation, bullet.hitColor); - shootSound.at(x + bulletOffset.x, y + bulletOffset.y, Mathf.random(0.9f, 1.1f)); + fshootEffect.at(bulletX, bulletY, rotation, type.hitColor); + fsmokeEffect.at(bulletX, bulletY, rotation, type.hitColor); + shootSound.at(bulletX, bulletY, Mathf.random(0.9f, 1.1f)); if(shootShake > 0){ Effect.shake(shootShake, shootShake, this); @@ -582,6 +579,10 @@ public class Turret extends ReloadTurret{ recoil = recoilAmount; } + protected void handleBullet(@Nullable Bullet bullet){ + + } + protected void ejectEffects(){ if(dead) return; diff --git a/gradle.properties b/gradle.properties index 92b97e3f8b..55579eee48 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,4 @@ android.useAndroidX=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=801bc93181 +archash=62774bbfce