diff --git a/core/assets-raw/sprites/blocks/environment/arkyic-wall-large.png b/core/assets-raw/sprites/blocks/environment/arkyic-wall-large.png new file mode 100644 index 0000000000..a972142d22 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/arkyic-wall-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/arkyic-wall1.png b/core/assets-raw/sprites/blocks/environment/arkyic-wall1.png new file mode 100644 index 0000000000..0df834af2e Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/arkyic-wall1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/arkyic-wall2.png b/core/assets-raw/sprites/blocks/environment/arkyic-wall2.png new file mode 100644 index 0000000000..45b1197fc4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/arkyic-wall2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/arkyic-wall3.png b/core/assets-raw/sprites/blocks/environment/arkyic-wall3.png new file mode 100644 index 0000000000..e289f569a4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/arkyic-wall3.png differ diff --git a/core/assets-raw/sprites/blocks/production/electric-heater-liquid.png b/core/assets-raw/sprites/blocks/production/electric-heater-liquid.png deleted file mode 100644 index 1c8f9ac253..0000000000 Binary files a/core/assets-raw/sprites/blocks/production/electric-heater-liquid.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/production/heat-redirector-glow.png b/core/assets-raw/sprites/blocks/production/heat-redirector-glow.png new file mode 100644 index 0000000000..87109515fc Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-redirector-glow.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-redirector-heat.png b/core/assets-raw/sprites/blocks/production/heat-redirector-heat.png new file mode 100644 index 0000000000..0115ebd9c5 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-redirector-heat.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-redirector-top1.png b/core/assets-raw/sprites/blocks/production/heat-redirector-top1.png new file mode 100644 index 0000000000..ae2463b4b3 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-redirector-top1.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-redirector-top2.png b/core/assets-raw/sprites/blocks/production/heat-redirector-top2.png new file mode 100644 index 0000000000..1cafe50705 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-redirector-top2.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-redirector.png b/core/assets-raw/sprites/blocks/production/heat-redirector.png new file mode 100644 index 0000000000..d664306eaa Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-redirector.png differ diff --git a/core/assets-raw/sprites/blocks/production/phase-heater-heat.png b/core/assets-raw/sprites/blocks/production/phase-heater-heat.png new file mode 100644 index 0000000000..21a8096ff6 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/phase-heater-heat.png differ diff --git a/core/assets-raw/sprites/blocks/production/phase-heater-side2.png b/core/assets-raw/sprites/blocks/production/phase-heater-side2.png new file mode 100644 index 0000000000..e3d0222dae Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/phase-heater-side2.png differ diff --git a/core/assets-raw/sprites/blocks/production/phase-heater-top1.png b/core/assets-raw/sprites/blocks/production/phase-heater-top1.png new file mode 100644 index 0000000000..75c0a1a1e3 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/phase-heater-top1.png differ diff --git a/core/assets-raw/sprites/blocks/production/phase-heater-top2.png b/core/assets-raw/sprites/blocks/production/phase-heater-top2.png new file mode 100644 index 0000000000..293114bdc7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/phase-heater-top2.png differ diff --git a/core/assets-raw/sprites/blocks/production/phase-heater.png b/core/assets-raw/sprites/blocks/production/phase-heater.png new file mode 100644 index 0000000000..3563a591b4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/phase-heater.png differ diff --git a/core/assets-raw/sprites/units/vanquish.png b/core/assets-raw/sprites/units/vanquish.png new file mode 100644 index 0000000000..d8ec8ea8a9 Binary files /dev/null and b/core/assets-raw/sprites/units/vanquish.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 811a2c8627..abfecb82bc 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -714,6 +714,7 @@ stat.showinmap = stat.description = Purpose stat.input = Input stat.output = Output +stat.maxefficiency = Max Efficiency stat.booster = Booster stat.tiles = Required Tiles stat.affinities = Affinities @@ -815,6 +816,7 @@ bar.capacity = Capacity: {0} bar.unitcap = {0} {1}/{2} bar.liquid = Liquid bar.heat = Heat +bar.heatamount = Heat: {0} bar.heatpercent = Heat: {0} ({1}%) bar.power = Power bar.progress = Build Progress @@ -1098,12 +1100,22 @@ item.metaglass.name = Metaglass item.scrap.name = Scrap item.fissile-matter.name = Fissile Matter item.beryllium.name = Beryllium +item.tungsten.name = Tungsten +item.oxide.name = Oxide +item.carbide.name = Carbide +item.dormant-cyst.name = Dormant Cyst liquid.water.name = Water liquid.slag.name = Slag liquid.oil.name = Oil liquid.cryofluid.name = Cryofluid liquid.neoplasm.name = Neoplasm +liquid.arkycite.name = Arkycite +liquid.gallium.name = Gallium +liquid.ozone.name = Ozone +liquid.hydrogen.name = Hydrogen +liquid.nitrogen.name = Nitrogen +liquid.cyanogen.name = Cyanogen unit.dagger.name = Dagger unit.mace.name = Mace diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 6234b6f393..8e10964f1d 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -480,3 +480,6 @@ 63226=eletric-heater|block-eletric-heater-ui 63225=vent-condenser|block-vent-condenser-ui 63224=electric-heater|block-electric-heater-ui +63223=phase-heater|block-phase-heater-ui +63222=arkyic-wall|block-arkyic-wall-ui +63221=heat-redirector|block-heat-redirector-ui diff --git a/core/assets/logicids.dat b/core/assets/logicids.dat index be4c828ec6..7125675ef5 100644 Binary files a/core/assets/logicids.dat and b/core/assets/logicids.dat differ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 465719efff..813b7cced2 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -44,7 +44,7 @@ public class Blocks{ redmat, bluemat, stoneWall, dirtWall, sporeWall, iceWall, daciteWall, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster, redweed, purbush, coralChunk, yellowCoral, - regolithWall, yellowStoneWall, rhyoliteWall, steamVent, carbonWall, redIceWall, ferricStoneWall, beryllicStoneWall, + regolithWall, yellowStoneWall, rhyoliteWall, steamVent, carbonWall, redIceWall, ferricStoneWall, beryllicStoneWall, arkyicWall, ferricStone, ferricCraters, carbonStone, beryllicStone, iceSnow, sandWater, darksandWater, duneWall, sandWall, moss, sporeMoss, shale, shaleWall, grass, salt, shaleBoulder, sandBoulder, daciteBoulder, boulder, snowBoulder, basaltBoulder, carbonBoulder, ferricBoulder, beryllicBoulder, yellowStoneBoulder, @@ -64,7 +64,7 @@ public class Blocks{ melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge, //erekir - siliconArcFurnace, electrolyzer, oxidationChamber, atmosphericConcentrator, electricHeater, slagIncinerator, + siliconArcFurnace, electrolyzer, oxidationChamber, atmosphericConcentrator, electricHeater, phaseHeater, heatRedirector, slagIncinerator, carbideCrucible, slagCentrifuge, surgeCrucible, cyanogenSynthesizer, phaseSynthesizer, heatReactor, cellSynthesisChamber, @@ -519,6 +519,11 @@ public class Blocks{ attributes.set(Attribute.silicate, 1.2f); }}; + arkyicWall = new StaticWall("arkyic-wall"){{ + variants = 3; + arkyciteFloor.asFloor().wall = arkyicStone.asFloor().wall = this; + }}; + redIceWall = new StaticWall("red-ice-wall"){{ redIce.asFloor().wall = this; }}; @@ -1081,6 +1086,25 @@ public class Blocks{ consumes.power(0.5f / 60f); }}; + phaseHeater = new HeatProducer("phase-heater"){{ + requirements(Category.crafting, with(Items.oxide, 30, Items.carbide, 30)); + + drawer = new DrawMulti(new DrawHeatOutput(true)); + drawer.iconOverride = new String[]{""}; + size = 2; + heatOutput = 10f; + craftTime = 60f * 8f; + consumes.item(Items.phaseFabric); + consumes.power(0.5f / 60f); + }}; + + heatRedirector = new HeatConductor("heat-redirector"){{ + requirements(Category.crafting, with(Items.tungsten, 10, Items.graphite, 10)); + + size = 3; + drawer = new DrawMulti(new DrawHeatOutput(true), new DrawHeatInput("-heat")); + }}; + 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 1d01dab76a..2855ab91c8 100644 --- a/core/src/mindustry/content/ErekirTechTree.java +++ b/core/src/mindustry/content/ErekirTechTree.java @@ -89,7 +89,9 @@ public class ErekirTechTree{ node(carbideCrucible, () -> { node(surgeCrucible, () -> { node(phaseSynthesizer, () -> { + node(phaseHeater, () -> { + }); }); }); }); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 820917bc4d..b5afe88109 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -34,6 +34,7 @@ import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.*; import mindustry.world.blocks.environment.*; import mindustry.world.blocks.heat.*; +import mindustry.world.blocks.heat.HeatConductor.*; import mindustry.world.blocks.logic.LogicBlock.*; import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.power.*; @@ -285,17 +286,36 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, } public float calculateHeat(float[] sideHeat){ + 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(); + float heat = 0f; 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)){ - //heat is distributed across building size - float add = heater.heat() / build.block.size; + if(build != null && build.team == team && build instanceof HeatBlock heater && (!build.block.rotate || (relativeTo(build) + 2) % 4 == 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; + + 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); + } + } } } return heat; diff --git a/core/src/mindustry/graphics/MinimapRenderer.java b/core/src/mindustry/graphics/MinimapRenderer.java index 8f43b150ec..6bae42920e 100644 --- a/core/src/mindustry/graphics/MinimapRenderer.java +++ b/core/src/mindustry/graphics/MinimapRenderer.java @@ -114,6 +114,8 @@ public class MinimapRenderer{ } Draw.reset(); + + //TODO might be useful in the standard minimap too if(withLabels){ drawSpawns(x, y, w, h, scaling); } diff --git a/core/src/mindustry/io/JsonIO.java b/core/src/mindustry/io/JsonIO.java index b3984444ab..8cc9119fcc 100644 --- a/core/src/mindustry/io/JsonIO.java +++ b/core/src/mindustry/io/JsonIO.java @@ -225,10 +225,10 @@ public class JsonIO{ public UnlockableContent read(Json json, JsonValue jsonData, Class type){ if(jsonData.isNull()) return null; String str = jsonData.asString(); - Item item = Vars.content.getByName(ContentType.item, str); - Liquid liquid = Vars.content.getByName(ContentType.liquid, str); - Block block = Vars.content.getByName(ContentType.block, str); - UnitType unit = Vars.content.getByName(ContentType.unit, str); + Item item = Vars.content.item(str); + Liquid liquid = Vars.content.liquid(str); + Block block = Vars.content.block(str); + UnitType unit = Vars.content.unit(str); return item != null ? item : liquid != null ? liquid : diff --git a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java index e6e99807b2..4f3a229ead 100644 --- a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java @@ -45,7 +45,7 @@ public class ErekirPlanetGenerator extends PlanetGenerator{ @Override public float getSizeScl(){ - return 2000; + return 2000 * 1.06f; } @Override @@ -92,7 +92,7 @@ public class ErekirPlanetGenerator extends PlanetGenerator{ tile.block = tile.floor.asFloor().wall; - if(Ridged.noise3d(1, position.x, position.y, position.z, 2, 25) > 0.19){ + if(Ridged.noise3d(1, position.x, position.y, position.z, 2, 14) > 0.15){ tile.block = Blocks.air; } @@ -160,6 +160,10 @@ public class ErekirPlanetGenerator extends PlanetGenerator{ median(3, 0.6, Blocks.slag); pass((x, y) -> { + if((floor == Blocks.arkyciteFloor || floor == Blocks.arkyicStone) && block.isStatic()){ + block = Blocks.arkyicWall; + } + float max = 0; for(Point2 p : Geometry.d8){ max = Math.max(max, world.getDarkness(x + p.x, y + p.y)); diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java index 0637ed8c2b..8b28d8808b 100644 --- a/core/src/mindustry/type/Sector.java +++ b/core/src/mindustry/type/Sector.java @@ -9,6 +9,7 @@ import arc.math.geom.*; import arc.struct.*; import arc.util.*; import mindustry.*; +import mindustry.content.*; import mindustry.game.Saves.*; import mindustry.game.*; import mindustry.gen.*; @@ -85,6 +86,12 @@ public class Sector{ public void loadInfo(){ info = Core.settings.getJson(planet.name + "-s-" + id + "-info", SectorInfo.class, SectorInfo::new); + + //fix an old naming bug; this doesn't happen with new saves, but old saves need manual fixes + if(info.resources.contains(Blocks.water)){ + info.resources.remove(Blocks.water); + info.resources.add(Liquids.water); + } } /** Removes any sector info. */ diff --git a/core/src/mindustry/world/blocks/heat/HeatConductor.java b/core/src/mindustry/world/blocks/heat/HeatConductor.java index 67d8f6a75e..4979fefc17 100644 --- a/core/src/mindustry/world/blocks/heat/HeatConductor.java +++ b/core/src/mindustry/world/blocks/heat/HeatConductor.java @@ -1,6 +1,8 @@ package mindustry.world.blocks.heat; +import arc.*; import arc.graphics.g2d.*; +import arc.struct.*; import arc.util.*; import mindustry.entities.units.*; import mindustry.gen.*; @@ -10,12 +12,13 @@ import mindustry.world.*; import mindustry.world.draw.*; public class HeatConductor extends Block{ - public float visualMaxHeat = 10f; + public float visualMaxHeat = 15f; public DrawBlock drawer = new DrawBlock(); public HeatConductor(String name){ super(name); update = solid = rotate = true; + rotateDraw = false; size = 3; } @@ -23,7 +26,8 @@ public class HeatConductor extends Block{ public void setBars(){ super.setBars(); - bars.add("heat", (HeatConductorBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat / visualMaxHeat)); + //TODO show number + bars.add("heat", (HeatConductorBuild entity) -> new Bar(() -> Core.bundle.format("bar.heatamount", (int)entity.heat), () -> Pal.lightOrange, () -> entity.heat / visualMaxHeat)); } @Override @@ -43,8 +47,10 @@ public class HeatConductor extends Block{ return drawer.finalIcons(this); } - public class HeatConductorBuild extends Building implements HeatBlock{ + public class HeatConductorBuild extends Building implements HeatBlock, HeatConsumer{ public float heat = 0f; + public float[] sideHeat = new float[4]; + public IntSet cameFrom = new IntSet(); @Override public void draw(){ @@ -57,9 +63,19 @@ public class HeatConductor extends Block{ drawer.drawLights(this); } + @Override + public float[] sideHeat(){ + return sideHeat; + } + + @Override + public float heatRequirement(){ + return visualMaxHeat; + } + @Override public void updateTile(){ - heat = calculateHeat(null); + heat = calculateHeat(sideHeat, cameFrom); } @Override diff --git a/core/src/mindustry/world/blocks/heat/HeatConsumer.java b/core/src/mindustry/world/blocks/heat/HeatConsumer.java new file mode 100644 index 0000000000..f59569a98e --- /dev/null +++ b/core/src/mindustry/world/blocks/heat/HeatConsumer.java @@ -0,0 +1,6 @@ +package mindustry.world.blocks.heat; + +public interface HeatConsumer{ + float[] sideHeat(); + float heatRequirement(); +} diff --git a/core/src/mindustry/world/blocks/production/HeatCrafter.java b/core/src/mindustry/world/blocks/production/HeatCrafter.java index 7ce4a20fd0..a2eb5d11dc 100644 --- a/core/src/mindustry/world/blocks/production/HeatCrafter.java +++ b/core/src/mindustry/world/blocks/production/HeatCrafter.java @@ -4,6 +4,7 @@ import arc.*; import arc.math.*; import mindustry.graphics.*; import mindustry.ui.*; +import mindustry.world.blocks.heat.*; import mindustry.world.meta.*; /** A crafter that requires contact from heater blocks to craft. */ @@ -35,9 +36,10 @@ public class HeatCrafter extends GenericCrafter{ super.setStats(); stats.add(Stat.input, heatRequirement, StatUnit.heatUnits); + stats.add(Stat.maxEfficiency, (int)(maxEfficiency * 100f), StatUnit.percent); } - public class HeatCrafterBuild extends GenericCrafterBuild{ + public class HeatCrafterBuild extends GenericCrafterBuild implements HeatConsumer{ //TODO sideHeat could be smooth public float[] sideHeat = new float[4]; public float heat = 0f; @@ -49,10 +51,16 @@ public class HeatCrafter extends GenericCrafter{ super.updateTile(); } + @Override public float heatRequirement(){ return heatRequirement; } + @Override + public float[] sideHeat(){ + return sideHeat; + } + @Override public float warmupTarget(){ return Mathf.clamp(heat / heatRequirement); diff --git a/core/src/mindustry/world/draw/DrawHeatInput.java b/core/src/mindustry/world/draw/DrawHeatInput.java index 17462fc553..bb5005ac71 100644 --- a/core/src/mindustry/world/draw/DrawHeatInput.java +++ b/core/src/mindustry/world/draw/DrawHeatInput.java @@ -4,27 +4,42 @@ import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; +import arc.util.*; +import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.world.*; -import mindustry.world.blocks.production.HeatCrafter.*; +import mindustry.world.blocks.heat.*; /** Not standalone. */ public class DrawHeatInput extends DrawBlock{ + public String suffix = "-heat"; public Color heatColor = new Color(1f, 0.22f, 0.22f, 0.8f); public float heatPulse = 0.3f, heatPulseScl = 10f; public TextureRegion heat; + public DrawHeatInput(String suffix){ + this.suffix = suffix; + } + + public DrawHeatInput(){ + } + + @Override + public void drawPlan(Block block, BuildPlan plan, Eachable list){ + } + @Override public void drawBase(Building build){ Draw.z(Layer.blockAdditive); - if(build instanceof HeatCrafterBuild hc){ + if(build instanceof HeatConsumer hc){ + float[] side = hc.sideHeat(); for(int i = 0; i < 4; i++){ - if(hc.sideHeat[i] > 0){ + if(side[i] > 0){ Draw.blend(Blending.additive); - Draw.color(heatColor, hc.sideHeat[i] / hc.heatRequirement() * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); + Draw.color(heatColor, side[i] / hc.heatRequirement() * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); Draw.rect(heat, build.x, build.y, i * 90f); Draw.blend(); Draw.color(); @@ -37,6 +52,6 @@ public class DrawHeatInput extends DrawBlock{ @Override public void load(Block block){ - heat = Core.atlas.find(block.name + "-heat"); + heat = Core.atlas.find(block.name + suffix); } } diff --git a/core/src/mindustry/world/meta/Stat.java b/core/src/mindustry/world/meta/Stat.java index 134070bd5d..5d341d5def 100644 --- a/core/src/mindustry/world/meta/Stat.java +++ b/core/src/mindustry/world/meta/Stat.java @@ -61,6 +61,7 @@ public enum Stat{ input(StatCat.crafting), output(StatCat.crafting), productionTime(StatCat.crafting), + maxEfficiency(StatCat.crafting), drillTier(StatCat.crafting), drillSpeed(StatCat.crafting), linkRange(StatCat.crafting),