diff --git a/core/assets-raw/sprites/units/weapons/conquer-weapon-fold.png b/core/assets-raw/sprites/units/weapons/conquer-weapon-fold.png deleted file mode 100644 index 9ef6827464..0000000000 Binary files a/core/assets-raw/sprites/units/weapons/conquer-weapon-fold.png and /dev/null differ diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index 5f903ac9c3..f4ebebe16f 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -205,5 +205,3 @@ const ResizeEvent = Packages.mindustry.game.EventType.ResizeEvent const LoseEvent = Packages.mindustry.game.EventType.LoseEvent const WinEvent = Packages.mindustry.game.EventType.WinEvent const Trigger = Packages.mindustry.game.EventType.Trigger -const PlayerConnectionConfirmed = Packages.mindustry.game.EventType.PlayerConnectionConfirmed -const AdminRequestEvent = Packages.mindustry.game.EventType.AdminRequestEvent diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 6a063797ae..9b0a534038 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1482,13 +1482,13 @@ public class Blocks{ tungstenWall = new Wall("tungsten-wall"){{ requirements(Category.defense, with(Items.tungsten, 6)); health = 180 * wallHealthMultiplier; - armor = 10f; + armor = 14f; }}; tungstenWallLarge = new Wall("tungsten-wall-large"){{ requirements(Category.defense, ItemStack.mult(tungstenWall.requirements, 4)); health = 180 * wallHealthMultiplier * 4; - armor = 10f; + armor = 14f; size = 2; }}; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 50bbd4b49e..5db681f255 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2529,6 +2529,7 @@ public class UnitTypes{ shootWarmupSpeed = 0.06f; cooldownTime = 110f; heatColor = Color.valueOf("f9350f"); + minWarmup = 0.9f; parts.addAll( new RegionPart("-glow"){{ @@ -2588,13 +2589,13 @@ public class UnitTypes{ }}); } - bullet = new BasicBulletType(8.5f, 250){{ + bullet = new BasicBulletType(8f, 250){{ sprite = "missile-large"; width = 12f; height = 20f; - lifetime = 30f; + lifetime = 35f; hitSize = 6f; - shootEffect = Fx.shootTitan; + smokeEffect = Fx.shootSmokeTitan; pierceCap = 3; pierce = true; @@ -2602,8 +2603,71 @@ public class UnitTypes{ hitColor = backColor = trailColor = Color.valueOf("feb380"); frontColor = Color.white; trailWidth = 4f; - trailLength = 8; - hitEffect = despawnEffect = Fx.blastExplosion; + trailLength = 9; + hitEffect = despawnEffect = Fx.massiveExplosion; + + shootEffect = new ExplosionEffect(){{ + lifetime = 40f; + waveStroke = 4f; + waveColor = sparkColor = trailColor; + waveRad = 15f; + smokeSize = 5f; + smokes = 8; + smokeSizeBase = 0f; + smokeColor = trailColor; + sparks = 8; + sparkRad = 40f; + sparkLen = 4f; + sparkStroke = 3f; + }}; + + //trailChance = 0.1f; + trailInterval = 3f; + trailParam = 4f; + + int count = 6; + for(int j = 0; j < count; j++){ + int s = j; + for(int i : Mathf.signs){ + float fin = 0.05f + (j + 1) / (float)count; + float spd = speed; + float life = lifetime / Mathf.lerp(fin, 1f, 0.5f); + spawnBullets.add(new BasicBulletType(spd * (fin), 40){{ + drag = 0.002f; + width = 8f; + height = 10f; + lifetime = life + 5f; + weaveRandom = false; + hitSize = 5f; + pierceCap = 2; + pierce = true; + pierceBuilding = true; + hitColor = backColor = trailColor = Color.valueOf("feb380"); + frontColor = Color.white; + trailWidth = 2.5f; + trailLength = 7; + weaveScale = (3f + s/2f) / 1.2f; + weaveMag = i * (4f - fin * 2f); + + splashDamage = 40f; + splashDamageRadius = 25f; + despawnEffect = new ExplosionEffect(){{ + lifetime = 50f; + waveStroke = 4f; + waveColor = sparkColor = trailColor; + waveRad = 30f; + smokeSize = 7f; + smokes = 6; + smokeSizeBase = 0f; + smokeColor = trailColor; + sparks = 5; + sparkRad = 30f; + sparkLen = 3f; + sparkStroke = 1.5f; + }}; + }}); + } + } }}; }}); diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index bf9b66a03f..0ee7e4e2d9 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -142,6 +142,7 @@ public class BulletType extends Content implements Cloneable{ public @Nullable BulletType fragBullet = null; public Color hitColor = Color.white; public Color healColor = Pal.heal; + /** Bullets spawned when this bullet is created. Rarely necessary, used for visuals. */ public Seq spawnBullets = new Seq<>(); public Color trailColor = Pal.missileYellowBack; @@ -178,7 +179,8 @@ public class BulletType extends Content implements Cloneable{ public @Nullable BulletType lightningType = null; public float weaveScale = 1f; - public float weaveMag = -1f; + public float weaveMag = 0f; + public boolean weaveRandom = true; public float hitShake = 0f, despawnShake = 0f; public int puddles; @@ -375,6 +377,12 @@ public class BulletType extends Content implements Cloneable{ if(instantDisappear){ b.time = lifetime; } + + if(spawnBullets.size > 0){ + for(var bullet : spawnBullets){ + bullet.create(b, b.x, b.y, b.rotation()); + } + } } public void update(Bullet b){ @@ -397,8 +405,8 @@ public class BulletType extends Content implements Cloneable{ } } - if(weaveMag > 0){ - b.vel.rotate(Mathf.sin(b.time + Mathf.PI * weaveScale/2f, weaveScale, weaveMag * (Mathf.randomSeed(b.id, 0, 1) == 1 ? -1 : 1)) * Time.delta); + if(weaveMag != 0){ + b.vel.rotateRadExact((float)Math.sin((b.time + Math.PI * weaveScale/2f) / weaveScale) * weaveMag * (weaveRandom ? (Mathf.randomSeed(b.id, 0, 1) == 1 ? -1 : 1) : 1f) * Time.delta * Mathf.degRad); } if(trailChance > 0){ diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index 553234c3d0..7f47e61784 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -92,6 +92,8 @@ public class Weapon implements Cloneable{ public float rotationLimit = 361f; /** ticks to cool down the heat region */ public float cooldownTime = 20f; + /** minimum weapon warmup before firing (this is not linear, do NOT use 1!) */ + public float minWarmup = 0f; /** lerp speed for shoot warmup, only used for parts */ public float shootWarmupSpeed = 0.1f, smoothReloadSpeed = 0.15f; /** random sound pitch range */ @@ -342,6 +344,7 @@ public class Weapon implements Cloneable{ can && //must be able to shoot (!useAmmo || unit.ammo > 0 || !state.rules.unitAmmo || unit.team.rules().infiniteAmmo) && //check ammo (!alternate || wasFlipped == flipSprite) && + mount.warmup >= minWarmup && //must be warmed up unit.vel.len() >= minShootVelocity && //check velocity requirements mount.reload <= 0.0001f && //reload has to be 0 Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, shootCone) //has to be within the cone diff --git a/core/src/mindustry/world/blocks/distribution/DirectionBridge.java b/core/src/mindustry/world/blocks/distribution/DirectionBridge.java index f7c9b6bc7a..d8ca0b81c2 100644 --- a/core/src/mindustry/world/blocks/distribution/DirectionBridge.java +++ b/core/src/mindustry/world/blocks/distribution/DirectionBridge.java @@ -183,21 +183,10 @@ public class DirectionBridge extends Block{ for(int dir = 0; dir < 4; dir++){ if(dir != rotation){ int dx = Geometry.d4x(dir), dy = Geometry.d4y(dir); - int length = range; - Building found = null; - - //find the link - for(int i = 1; i <= range; i++){ - Tile other = world.tile(tile.x + dx * i, tile.y + dy * i); - - if(other != null && other.build instanceof DirectionBridgeBuild build && build.block == DirectionBridge.this && build.team == player.team() && (build.rotation + 2) % 4 == dir){ - length = i; - found = other.build; - break; - } - } + Building found = occupied[(dir + 2) % 4]; if(found != null){ + int length = Math.max(Math.abs(found.tileX() - tileX()), Math.abs(found.tileY() - tileY())); Drawf.dashLine(Pal.place, found.x - dx * (tilesize / 2f + 2), found.y - dy * (tilesize / 2f + 2),