diff --git a/core/assets-raw/sprites/blocks/attack/nuclear-warhead.png b/core/assets-raw/sprites/blocks/attack/nuclear-warhead.png deleted file mode 100644 index 6963fe4a52..0000000000 Binary files a/core/assets-raw/sprites/blocks/attack/nuclear-warhead.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/drills/plasma-bore-glow.png b/core/assets-raw/sprites/blocks/drills/plasma-bore-glow.png index 1ae3205f02..c0d753b707 100644 Binary files a/core/assets-raw/sprites/blocks/drills/plasma-bore-glow.png and b/core/assets-raw/sprites/blocks/drills/plasma-bore-glow.png differ diff --git a/core/assets-raw/sprites/blocks/drills/surge-drill.png b/core/assets-raw/sprites/blocks/drills/surge-drill.png new file mode 100644 index 0000000000..b982da64a0 Binary files /dev/null and b/core/assets-raw/sprites/blocks/drills/surge-drill.png differ diff --git a/core/assets-raw/sprites/blocks/payload/warhead-assembler.png b/core/assets-raw/sprites/blocks/payload/warhead-assembler.png deleted file mode 100644 index f65306b2f0..0000000000 Binary files a/core/assets-raw/sprites/blocks/payload/warhead-assembler.png and /dev/null differ diff --git a/core/assets-raw/sprites/effects/drill-laser-boost-center.png b/core/assets-raw/sprites/effects/drill-laser-boost-center.png new file mode 100644 index 0000000000..e8ed8c4a68 Binary files /dev/null and b/core/assets-raw/sprites/effects/drill-laser-boost-center.png differ diff --git a/core/assets-raw/sprites/effects/drill-laser-boost-end.png b/core/assets-raw/sprites/effects/drill-laser-boost-end.png new file mode 100644 index 0000000000..417d6eb411 Binary files /dev/null and b/core/assets-raw/sprites/effects/drill-laser-boost-end.png differ diff --git a/core/assets-raw/sprites/effects/drill-laser-boost.png b/core/assets-raw/sprites/effects/drill-laser-boost.png new file mode 100644 index 0000000000..f2ae1a24f2 Binary files /dev/null and b/core/assets-raw/sprites/effects/drill-laser-boost.png differ diff --git a/core/src/mindustry/async/AsyncCore.java b/core/src/mindustry/async/AsyncCore.java index 5de761d0ca..df07bda1ac 100644 --- a/core/src/mindustry/async/AsyncCore.java +++ b/core/src/mindustry/async/AsyncCore.java @@ -77,7 +77,7 @@ public class AsyncCore{ private void complete(){ //wait for all threads to stop processing - for(Future future : futures){ + for(var future : futures){ try{ future.get(); }catch(Throwable t){ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 614c44d236..572aafbaa6 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -121,7 +121,7 @@ public class Blocks{ duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, foreshadow, spectre, meltdown, segment, parallax, tsunami, //turrets - erekir - breach, sublimate, titan, + breach, sublimate, titan, afflict, //units commandCenter, @@ -2266,7 +2266,7 @@ public class Blocks{ }}; cliffCrusher = new WallCrafter("cliff-crusher"){{ - requirements(Category.production, with(Items.graphite, 20, Items.beryllium, 20)); + requirements(Category.production, with(Items.graphite, 25, Items.beryllium, 20)); consumes.power(0.8f); @@ -2282,7 +2282,7 @@ public class Blocks{ drillTime = 150f; tier = 4; size = 2; - range = 3; + range = 4; consumes.liquid(Liquids.hydrogen, 0.25f / 60f).boost(); }}; @@ -2929,6 +2929,9 @@ public class Blocks{ ); //TODO no coolant? + coolantUsage = 10f / 60f; + coolantOverride = Liquids.water; + coolantMultiplier = 6f; shootShake = 1f; ammoPerShot = 6; @@ -2997,6 +3000,7 @@ public class Blocks{ length = range; }}; + acceptCoolant = false; scaledHealth = 320; shootLength = 7f; size = 3; @@ -3045,7 +3049,8 @@ public class Blocks{ shootLength = 7f; rotateSpeed = 2.5f; - acceptCoolant = false; + coolantUsage = 30f / 60f; + coolantOverride = Liquids.water; draw = new DrawTurret("reinforced-"){{ parts.addAll( diff --git a/core/src/mindustry/content/ErekirTechTree.java b/core/src/mindustry/content/ErekirTechTree.java index 9e490643a4..72cbd4a736 100644 --- a/core/src/mindustry/content/ErekirTechTree.java +++ b/core/src/mindustry/content/ErekirTechTree.java @@ -2,6 +2,7 @@ package mindustry.content; import arc.struct.*; import mindustry.game.Objectives.*; +import mindustry.type.*; import static mindustry.content.Blocks.*; import static mindustry.content.TechTree.*; @@ -11,6 +12,13 @@ public class ErekirTechTree{ public static void load(){ Seq erekirSector = Seq.with(new OnPlanet(Planets.erekir)); + //TODO use these multipliers! + var costMultipliers = new ObjectFloatMap(); + costMultipliers.put(Items.silicon, 4); + costMultipliers.put(Items.surgeAlloy, 4); + costMultipliers.put(Items.thorium, 6); + costMultipliers.put(Items.graphite, 5); + Planets.erekir.techTree = nodeRoot("erekir", coreBastion, true, () -> { node(duct, () -> { node(ductRouter, () -> { diff --git a/core/src/mindustry/content/Items.java b/core/src/mindustry/content/Items.java index 34dd7bb293..ae76f8916c 100644 --- a/core/src/mindustry/content/Items.java +++ b/core/src/mindustry/content/Items.java @@ -92,7 +92,7 @@ public class Items{ pyratite = new Item("pyratite", Color.valueOf("ffaa5f")){{ flammability = 1.4f; - explosiveness = 0.5f; + explosiveness = 0.4f; }}; beryllium = new Item("beryllium", Color.valueOf("3a8f64")){{ @@ -113,7 +113,7 @@ public class Items{ }}; carbide = new Item("carbide", Color.valueOf("89769a")){{ - cost = 1.6f; + cost = 1.4f; healthScaling = 1.1f; }}; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a07477ed3c..28515f02de 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -69,15 +69,14 @@ public class UnitTypes{ public static @EntityDef({Unitc.class, BlockUnitc.class}) UnitType block; //special tethered (has payload capability, because it's necessary sometimes) - public static @EntityDef({Unitc.class, BuildingTetherc.class, Payloadc.class}) UnitType manifold, assemblyDrone, payloadDrone; + public static @EntityDef({Unitc.class, BuildingTetherc.class, Payloadc.class}) UnitType manifold, assemblyDrone; //tank - //TODO tank comp public static @EntityDef({Unitc.class, Tankc.class}) UnitType vanquish; //endregion - //missile definition, needed for codegen + //missile definition, unused here but needed for codegen public static @EntityDef({Unitc.class, TimedKillc.class}) UnitType missile; //region neoplasm @@ -2525,10 +2524,8 @@ public class UnitTypes{ y = 1f; }}); - float es = 3.9f; - setEnginesMirror( - new UnitEngine(62 / 4f, -60 / 4f, es, 315f), + new UnitEngine(62 / 4f, -60 / 4f, 3.9f, 315f), new UnitEngine(72 / 4f, -29 / 4f, 3f, 315f) ); }}; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index a379818b10..b81ef11dc8 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -271,6 +271,8 @@ public class Block extends UnlockableContent{ public Effect destroyEffect = Fx.dynamicExplosion; /** Multiplier for cost of research in tech tree. */ public float researchCostMultiplier = 1; + /** Multipliers for research costs on a per-item basis. Format: ID to multiplier. */ + public ObjectFloatMap researchCostMultipliers = new ObjectFloatMap<>(); /** Whether this block has instant transfer.*/ public boolean instantTransfer = false; /** Whether you can rotate this block after it is placed. */ @@ -867,7 +869,7 @@ public class Block extends UnlockableContent{ public ItemStack[] researchRequirements(){ ItemStack[] out = new ItemStack[requirements.length]; for(int i = 0; i < out.length; i++){ - int quantity = 60 + Mathf.round(Mathf.pow(requirements[i].amount, 1.1f) * 20 * researchCostMultiplier, 10); + int quantity = 60 + Mathf.round(Mathf.pow(requirements[i].amount, 1.1f) * 20 * researchCostMultiplier * researchCostMultipliers.get(requirements[i].item, 1f), 10); out[i] = new ItemStack(requirements[i].item, UI.roundAmount(quantity)); } @@ -925,9 +927,6 @@ public class Block extends UnlockableContent{ scaling += stack.item.healthScaling; } - if(scaling > 1){ - Log.info("@: @ -> @", name, scaledHealth * size * size, (Mathf.round(scaledHealth * scaling, 5) * size * size)); - } scaledHealth *= scaling; round = true; } diff --git a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java index e3d33c56e2..ea9ca99e57 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/BaseTurret.java @@ -1,11 +1,13 @@ package mindustry.world.blocks.defense.turrets; import arc.struct.*; +import arc.util.*; import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.logic.*; +import mindustry.type.*; import mindustry.world.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; @@ -22,6 +24,8 @@ public class BaseTurret extends Block{ public Effect coolEffect = Fx.fuelburn; /** How much reload is lowered by for each unit of liquid of heat capacity. */ public float coolantMultiplier = 5f; + /** Liquid that is used by coolant; null to use default. */ + public @Nullable Liquid coolantOverride; public BaseTurret(String name){ super(name); @@ -39,7 +43,7 @@ public class BaseTurret extends Block{ public void init(){ if(acceptCoolant && !consumes.has(ConsumeType.liquid)){ hasLiquids = true; - consumes.add(new ConsumeCoolant(coolantUsage)).update(false).boost(); + consumes.add(coolantOverride != null ? new ConsumeLiquid(coolantOverride, coolantUsage) : new ConsumeCoolant(coolantUsage)).update(false).boost(); } super.init(); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java index b1688d1596..9e1051a14c 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -199,7 +199,7 @@ public class ItemTurret extends Turret{ } public class ItemEntry extends AmmoEntry{ - protected Item item; + public Item item; ItemEntry(Item item, int amount){ this.item = item; @@ -210,5 +210,13 @@ public class ItemTurret extends Turret{ public BulletType type(){ return ammoTypes.get(item); } + + @Override + public String toString(){ + return "ItemEntry{" + + "item=" + item + + ", amount=" + amount + + '}'; + } } } diff --git a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java index 729ecb3035..c16659490f 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ReloadTurret.java @@ -20,7 +20,7 @@ public class ReloadTurret extends BaseTurret{ super.setStats(); if(acceptCoolant){ - stats.add(Stat.booster, StatValues.boosters(reloadTime, consumes.get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> consumes.liquidfilters.get(l.id))); + stats.add(Stat.booster, StatValues.boosters(reloadTime, consumes.get(ConsumeType.liquid).amount, coolantMultiplier, true, l -> l.coolant && consumes.liquidfilters.get(l.id))); } } diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index f8cf19332f..ab466fb31c 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -466,8 +466,8 @@ public class Turret extends ReloadTurret{ /** @return whether the turret has ammo. */ public boolean hasAmmo(){ //skip first entry if it has less than the required amount of ammo - if(ammo.size >= 2 && ammo.peek().amount < ammoPerShot){ - ammo.pop(); + if(ammo.size >= 2 && ammo.peek().amount < ammoPerShot && ammo.get(ammo.size - 2).amount >= ammoPerShot){ + totalAmmo -= ammo.pop().amount; } return ammo.size > 0 && ammo.peek().amount >= ammoPerShot; } diff --git a/core/src/mindustry/world/blocks/distribution/DirectionBridge.java b/core/src/mindustry/world/blocks/distribution/DirectionBridge.java index 7addb04d30..f7c9b6bc7a 100644 --- a/core/src/mindustry/world/blocks/distribution/DirectionBridge.java +++ b/core/src/mindustry/world/blocks/distribution/DirectionBridge.java @@ -171,7 +171,7 @@ public class DirectionBridge extends Block{ Draw.rect(dirRegion, x, y, rotdeg()); var link = findLink(); if(link != null){ - Draw.z(Layer.power); + Draw.z(Layer.power - 1); drawBridge(rotation, x, y, link.x, link.y, null); } } diff --git a/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java b/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java index f9b62d0a7c..d55f77ed45 100644 --- a/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java +++ b/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java @@ -48,7 +48,7 @@ public class DirectionLiquidBridge extends DirectionBridge{ Draw.rect(dirRegion, x, y, rotdeg()); var link = findLink(); if(link != null){ - Draw.z(Layer.power); + Draw.z(Layer.power - 1); drawBridge(rotation, x, y, link.x, link.y, Tmp.c1.set(liquids.current().color).a(liquids.currentAmount() / liquidCapacity * liquids.current().color.a)); } } diff --git a/core/src/mindustry/world/blocks/production/BeamDrill.java b/core/src/mindustry/world/blocks/production/BeamDrill.java index 521845cfaa..904f35d323 100644 --- a/core/src/mindustry/world/blocks/production/BeamDrill.java +++ b/core/src/mindustry/world/blocks/production/BeamDrill.java @@ -25,6 +25,11 @@ public class BeamDrill extends Block{ public @Load("drill-laser") TextureRegion laser; public @Load("drill-laser-end") TextureRegion laserEnd; public @Load("drill-laser-center") TextureRegion laserCenter; + + public @Load("drill-laser-boost") TextureRegion laserBoost; + public @Load("drill-laser-boost-end") TextureRegion laserEndBoost; + public @Load("drill-laser-boost-center") TextureRegion laserCenterBoost; + public @Load("@-top") TextureRegion topRegion; public @Load("@-glow") TextureRegion glowRegion; @@ -33,7 +38,7 @@ public class BeamDrill extends Block{ public int tier = 1; public float laserWidth = 0.65f; /** How many times faster the drill will progress when boosted by an optional consumer. */ - public float optionalBoostIntensity = 2.5f; //TODO would be nice to change laser color when this is active. + public float optionalBoostIntensity = 2.5f; public Color sparkColor = Color.valueOf("fd9e81"), glowColor = Color.white; public float glowIntensity = 0.2f, pulseIntensity = 0.07f; @@ -41,6 +46,7 @@ public class BeamDrill extends Block{ public int sparks = 7; public float sparkRange = 10f, sparkLife = 27f, sparkRecurrence = 4f, sparkSpread = 45f, sparkSize = 3.5f; + public Color boostHeatColor = Color.sky.cpy().mul(0.87f); public Color heatColor = new Color(1f, 0.35f, 0.35f, 0.9f); public float heatPulse = 0.3f, heatPulseScl = 7f; @@ -185,7 +191,7 @@ public class BeamDrill extends Block{ public @Nullable Item lastItem; public float time; - public float warmup; + public float warmup, boostWarmup; public float lastDrillSpeed; @Override @@ -245,7 +251,10 @@ public class BeamDrill extends Block{ float multiplier = 1f; if(cons.optionalValid()){ + boostWarmup = Mathf.lerpDelta(boostWarmup, 1f, 0.1f); multiplier *= optionalBoostIntensity; + }else{ + boostWarmup = Mathf.lerpDelta(boostWarmup, 0f, 0.1f); } lastDrillSpeed = (facingAmount * multiplier * timeScale) / drillTime; @@ -291,26 +300,46 @@ public class BeamDrill extends Block{ Draw.z(Layer.power - 1); Draw.mixcol(glowColor, Mathf.absin(Time.time + i*5 + id*9, glowScl, glowIntensity)); if(Math.abs(p.x - face.x) + Math.abs(p.y - face.y) == 0){ - Draw.rect(laserCenter, lx, ly, width * laserCenter.width * Draw.scl, width * laserCenter.height * Draw.scl); + Draw.scl(width); + + if(boostWarmup < 0.99f){ + Draw.alpha(1f - boostWarmup); + Draw.rect(laserCenter, lx, ly); + } + + if(boostWarmup > 0.01f){ + Draw.alpha(boostWarmup); + Draw.rect(laserCenterBoost, lx, ly); + } + + Draw.scl(); }else{ - Drawf.laser(team, laser, laserEnd, - (p.x - dir.x/2f) * tilesize, - (p.y - dir.y/2f) * tilesize, - lx, ly, - width); + float lsx = (p.x - dir.x/2f) * tilesize, lsy = (p.y - dir.y/2f) * tilesize; + + if(boostWarmup < 0.99f){ + Draw.alpha(1f - boostWarmup); + Drawf.laser(team, laser, laserEnd, lsx, lsy, lx, ly, width); + } + + if(boostWarmup > 0.001f){ + Draw.alpha(boostWarmup); + Drawf.laser(team, laserBoost, laserEndBoost, lsx, lsy, lx, ly, width); + } } + Draw.color(); Draw.mixcol(); Draw.z(Layer.effect); Lines.stroke(warmup); rand.setState(i, id); Color col = face.wallDrop().color; + Color spark = Tmp.c3.set(sparkColor).lerp(boostHeatColor, boostWarmup); for(int j = 0; j < sparks; j++){ float fin = (Time.time / sparkLife + rand.random(sparkRecurrence + 1f)) % sparkRecurrence; float or = rand.range(2f); Tmp.v1.set(sparkRange * fin, 0).rotate(rotdeg() + rand.range(sparkSpread)); - Draw.color(sparkColor, col, fin); + Draw.color(spark, col, fin); float px = Tmp.v1.x, py = Tmp.v1.y; if(fin <= 1f) Lines.lineAngle(lx + px + or * ddx, ly + py + or * ddy, Angles.angle(px, py), Mathf.slope(fin) * sparkSize); } @@ -321,7 +350,7 @@ public class BeamDrill extends Block{ if(glowRegion.found()){ Draw.z(Layer.blockAdditive); Draw.blend(Blending.additive); - Draw.color(heatColor, warmup * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); + Draw.color(Tmp.c1.set(heatColor).lerp(boostHeatColor, boostWarmup), warmup * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); Draw.rect(glowRegion, x, y, rotdeg()); Draw.blend(); Draw.color();