diff --git a/core/assets-raw/sprites/blocks/production/heat-router-glow.png b/core/assets-raw/sprites/blocks/production/heat-router-glow.png new file mode 100644 index 0000000000..234616dd67 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-router-glow.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-router-heat.png b/core/assets-raw/sprites/blocks/production/heat-router-heat.png new file mode 100644 index 0000000000..dd574df57d Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-router-heat.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-router-top1.png b/core/assets-raw/sprites/blocks/production/heat-router-top1.png new file mode 100644 index 0000000000..b9cba509e5 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-router-top1.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-router-top2.png b/core/assets-raw/sprites/blocks/production/heat-router-top2.png new file mode 100644 index 0000000000..0d59002b17 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-router-top2.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-router.png b/core/assets-raw/sprites/blocks/production/heat-router.png new file mode 100644 index 0000000000..0120bf6b0b Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-router.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index ad64fbe654..c4b9a02281 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1605,6 +1605,7 @@ block.electric-heater.name = Electric Heater block.slag-heater.name = Slag Heater block.phase-heater.name = Phase Heater block.heat-redirector.name = Heat Redirector +block.heat-router.name = Heat Router block.slag-incinerator.name = Slag Incinerator block.carbide-crucible.name = Carbide Crucible block.slag-centrifuge.name = Slag Centrifuge @@ -1964,6 +1965,7 @@ block.electric-heater.description = Applies heat to structures. Requires large a block.slag-heater.description = Applies heat to structures. Requires slag. block.phase-heater.description = Applies heat to structures. Requires phase fabric. block.heat-redirector.description = Redirects accumulated heat to other blocks. +block.heat-router.description = Spreads accumulated heat in three output directions. block.electrolyzer.description = Converts water into hydrogen and ozone gas. Outputs resulting gases in two opposite directions, marked by corresponding colors. block.atmospheric-concentrator.description = Concentrates nitrogen from the atmosphere. Requires heat. block.surge-crucible.description = Forms surge alloy from slag and silicon. Requires heat. diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 927b14172d..e878bd06e3 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -580,3 +580,4 @@ 63103=neoplasia-reactor|block-neoplasia-reactor-ui 63102=sand-floor|block-sand-floor-ui 63101=crystalline-vent|block-crystalline-vent-ui +63100=heat-router|block-heat-router-ui diff --git a/core/assets/logicids.dat b/core/assets/logicids.dat index 99fbf56614..9fa464644f 100644 Binary files a/core/assets/logicids.dat and b/core/assets/logicids.dat differ diff --git a/core/src/mindustry/ai/RtsAI.java b/core/src/mindustry/ai/RtsAI.java index 0692446ef3..33cf265cfa 100644 --- a/core/src/mindustry/ai/RtsAI.java +++ b/core/src/mindustry/ai/RtsAI.java @@ -153,6 +153,7 @@ public class RtsAI{ } Building defend = null; + boolean defendingCore = false; //there is something to defend, see if it's worth the time if(damaged.size > 0){ @@ -182,6 +183,10 @@ public class RtsAI{ if(debug){ Vars.ui.showLabel("Defend, dst = " + (int)(best.dst(ax, ay)), 8f, best.x, best.y); } + + if(best instanceof CoreBuild){ + defendingCore = true; + } } } @@ -241,7 +246,9 @@ public class RtsAI{ } //assign a flag, so it will be "mobilized" more easily later - unit.flag = 1; + if(!defendingCore){ + unit.flag = 1; + } } } } diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 8e1601dc6d..77bf3237fb 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -73,7 +73,7 @@ public class Blocks{ melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge, //crafting - erekir - siliconArcFurnace, electrolyzer, oxidationChamber, atmosphericConcentrator, electricHeater, slagHeater, phaseHeater, heatRedirector, slagIncinerator, + siliconArcFurnace, electrolyzer, oxidationChamber, atmosphericConcentrator, electricHeater, slagHeater, phaseHeater, heatRedirector, heatRouter, slagIncinerator, carbideCrucible, slagCentrifuge, surgeCrucible, cyanogenSynthesizer, phaseSynthesizer, heatReactor, //sandbox @@ -1316,6 +1316,17 @@ public class Blocks{ regionRotated1 = 1; }}; + heatRouter = new HeatConductor("heat-router"){{ + requirements(Category.crafting, with(Items.tungsten, 10, Items.graphite, 10)); + + researchCostMultiplier = 10f; + + size = 3; + drawer = new DrawMulti(new DrawDefault(), new DrawHeatOutput(-1, false), new DrawHeatOutput(), new DrawHeatOutput(1, false), new DrawHeatInput("-heat")); + regionRotated1 = 1; + splitHeat = true; + }}; + slagIncinerator = new ItemIncinerator("slag-incinerator"){{ requirements(Category.crafting, with(Items.tungsten, 15)); size = 1; diff --git a/core/src/mindustry/content/ErekirTechTree.java b/core/src/mindustry/content/ErekirTechTree.java index c257b8ddb7..33537fb4b1 100644 --- a/core/src/mindustry/content/ErekirTechTree.java +++ b/core/src/mindustry/content/ErekirTechTree.java @@ -220,6 +220,10 @@ public class ErekirTechTree{ }); }); }); + + node(heatRouter, () -> { + + }); }); }); }); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 3072313adc..81396d5f7f 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -351,7 +351,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, return calculateHeat(sideHeat, null); } - //TODO can cameFrom be an IntSet? public float calculateHeat(float[] sideHeat, @Nullable IntSet cameFrom){ Arrays.fill(sideHeat, 0f); if(cameFrom != null) cameFrom.clear(); @@ -360,22 +359,31 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, for(var edge : block.getEdges()){ Building build = nearby(edge.x, edge.y); - if(build != null && build.team == team && build instanceof HeatBlock heater && (!build.block.rotate || (relativeTo(build) + 2) % 4 == build.rotation)){ //TODO hacky + if(build != null && build.team == team && build instanceof HeatBlock heater){ - //if there's a cycle, ignore its heat - if(!(build instanceof HeatConductorBuild hc && hc.cameFrom.contains(id()))){ - //heat is distributed across building size - float add = heater.heat() / build.block.size; + boolean split = build.block instanceof HeatConductor cond && cond.splitHeat; + // non-routers must face us, routers must face away - next to a redirector, they're forced to face away due to cycles anyway + if(!build.block.rotate || (!split && (relativeTo(build) + 2) % 4 == build.rotation) || (split && relativeTo(build) != build.rotation)){ //TODO hacky - sideHeat[Mathf.mod(relativeTo(build), 4)] += add; - heat += add; - } + //if there's a cycle, ignore its heat + if(!(build instanceof HeatConductorBuild hc && hc.cameFrom.contains(id()))){ + //heat is distributed across building size + float add = heater.heat() / build.block.size; + if(split){ + //heat routers split heat across 3 surfaces + add /= 3f; + } - //register traversed cycles - if(cameFrom != null){ - cameFrom.add(build.id); - if(build instanceof HeatConductorBuild hc){ - cameFrom.addAll(hc.cameFrom); + sideHeat[Mathf.mod(relativeTo(build), 4)] += add; + heat += add; + } + + //register traversed cycles + if(cameFrom != null){ + cameFrom.add(build.id); + if(build instanceof HeatConductorBuild hc){ + cameFrom.addAll(hc.cameFrom); + } } } } diff --git a/core/src/mindustry/world/blocks/heat/HeatConductor.java b/core/src/mindustry/world/blocks/heat/HeatConductor.java index a343b05b74..d039beba58 100644 --- a/core/src/mindustry/world/blocks/heat/HeatConductor.java +++ b/core/src/mindustry/world/blocks/heat/HeatConductor.java @@ -14,6 +14,7 @@ import mindustry.world.draw.*; public class HeatConductor extends Block{ public float visualMaxHeat = 15f; public DrawBlock drawer = new DrawDefault(); + public boolean splitHeat = false; public HeatConductor(String name){ super(name); @@ -90,7 +91,7 @@ public class HeatConductor extends Block{ @Override public float heatFrac(){ - return heat / visualMaxHeat; + return (heat / visualMaxHeat) / (splitHeat ? 3f : 1); } } } diff --git a/core/src/mindustry/world/draw/DrawHeatOutput.java b/core/src/mindustry/world/draw/DrawHeatOutput.java index 9f1077c837..031e9d9941 100644 --- a/core/src/mindustry/world/draw/DrawHeatOutput.java +++ b/core/src/mindustry/world/draw/DrawHeatOutput.java @@ -17,17 +17,28 @@ public class DrawHeatOutput extends DrawBlock{ public Color heatColor = new Color(1f, 0.22f, 0.22f, 0.8f); public float heatPulse = 0.3f, heatPulseScl = 10f, glowMult = 1.2f; + public int rotOffset = 0; + public boolean drawGlow = true; + + public DrawHeatOutput(){} + + public DrawHeatOutput(int rotOffset, boolean drawGlow){ + this.rotOffset = rotOffset; + this.drawGlow = drawGlow; + } + @Override public void draw(Building build){ - Draw.rect(build.rotation > 1 ? top2 : top1, build.x, build.y, build.rotdeg()); + float rotdeg = (build.rotation + rotOffset) * 90; + Draw.rect(Mathf.mod((build.rotation + rotOffset), 4) > 1 ? top2 : top1, build.x, build.y, rotdeg); if(build instanceof HeatBlock heater && heater.heat() > 0){ Draw.z(Layer.blockAdditive); Draw.blend(Blending.additive); Draw.color(heatColor, heater.heatFrac() * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); - if(heat.found()) Draw.rect(heat, build.x, build.y, build.rotdeg()); + if(heat.found()) Draw.rect(heat, build.x, build.y, rotdeg); Draw.color(Draw.getColor().mul(glowMult)); - if(glow.found()) Draw.rect(glow, build.x, build.y); + if(drawGlow && glow.found()) Draw.rect(glow, build.x, build.y); Draw.blend(); Draw.color(); } @@ -35,7 +46,7 @@ public class DrawHeatOutput extends DrawBlock{ @Override public void drawPlan(Block block, BuildPlan plan, Eachable list){ - Draw.rect(plan.rotation > 1 ? top2 : top1, plan.drawx(), plan.drawy(), plan.rotation * 90); + Draw.rect(Mathf.mod((plan.rotation + rotOffset), 4) > 1 ? top2 : top1, plan.drawx(), plan.drawy(), (plan.rotation + rotOffset) * 90); } @Override @@ -48,4 +59,4 @@ public class DrawHeatOutput extends DrawBlock{ //TODO currently no icons due to concerns with rotation -} +} \ No newline at end of file