diff --git a/core/assets-raw/sprites/blocks/production/heat-reactor-glow.png b/core/assets-raw/sprites/blocks/production/heat-reactor-glow.png new file mode 100644 index 0000000000..236059e1c8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-reactor-glow.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-reactor-heat.png b/core/assets-raw/sprites/blocks/production/heat-reactor-heat.png new file mode 100644 index 0000000000..63eda92a37 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-reactor-heat.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-reactor-top1.png b/core/assets-raw/sprites/blocks/production/heat-reactor-top1.png new file mode 100644 index 0000000000..68454936da Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-reactor-top1.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-reactor-top2.png b/core/assets-raw/sprites/blocks/production/heat-reactor-top2.png new file mode 100644 index 0000000000..b5861e05da Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-reactor-top2.png differ diff --git a/core/assets-raw/sprites/blocks/production/heat-reactor.png b/core/assets-raw/sprites/blocks/production/heat-reactor.png new file mode 100644 index 0000000000..a23dffaddb Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/heat-reactor.png differ diff --git a/core/assets-raw/sprites/units/incite.png b/core/assets-raw/sprites/units/incite.png new file mode 100644 index 0000000000..01d7d777bb Binary files /dev/null and b/core/assets-raw/sprites/units/incite.png differ diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index f452fb24f1..1ac8ca077d 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -435,3 +435,4 @@ 63273=core-aegis|block-core-aegis-ui 63272=core-citadel|block-core-citadel-ui 63271=core-acropolis|block-core-acropolis-ui +63270=heat-reactor|block-heat-reactor-ui diff --git a/core/assets/logicids.dat b/core/assets/logicids.dat index 2addc7299a..a9c5b29ed3 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 a32b4a25a4..3a0706c7e7 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -17,6 +17,7 @@ import mindustry.world.blocks.defense.*; import mindustry.world.blocks.defense.turrets.*; import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.environment.*; +import mindustry.world.blocks.heat.*; import mindustry.world.blocks.legacy.*; import mindustry.world.blocks.liquid.*; import mindustry.world.blocks.logic.*; @@ -59,7 +60,7 @@ public class Blocks implements ContentList{ //crafting siliconSmelter, siliconCrucible, siliconArcFurnace, kiln, graphitePress, plastaniumCompressor, multiPress, phaseWeaver, surgeSmelter, pyratiteMixer, blastMixer, cryofluidMixer, melter, separator, disassembler, sporePress, pulverizer, incinerator, coalCentrifuge, - carbideCrucible, + heatReactor, carbideCrucible, cellSynthesisChamber, //sandbox @@ -942,6 +943,13 @@ public class Blocks implements ContentList{ consumes.power(0.50f); }}; + heatReactor = new HeatProducer("heat-reactor"){{ + requirements(Category.crafting, with(Items.tungsten, 60, Items.graphite, 30)); + size = 3; + consumeTime = 60f * 10f; + consumes.item(Items.fissileMatter, 1); + }}; + carbideCrucible = new GenericCrafter("carbide-crucible"){{ requirements(Category.crafting, with(Items.tungsten, 60, Items.graphite, 30)); craftEffect = Fx.smeltsmoke; diff --git a/core/src/mindustry/content/Items.java b/core/src/mindustry/content/Items.java index 5c3d285f20..160c59cc15 100644 --- a/core/src/mindustry/content/Items.java +++ b/core/src/mindustry/content/Items.java @@ -98,7 +98,7 @@ public class Items implements ContentList{ cost = 1.3f; }}; - fissileMatter = new Item("fissile-matter", Color.valueOf("536631")){{ + fissileMatter = new Item("fissile-matter", Color.valueOf("5e988d")){{ radioactivity = 1.5f; }}; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 67cbdf015a..1a04d1cee3 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -40,7 +40,7 @@ public class UnitTypes implements ContentList{ //air public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra, - evoke; //elicit, incite? + evoke, incite; //elicit, incite? //air, legacy public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono; diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index acedbc1b26..4577287cd7 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -593,6 +593,17 @@ public class Block extends UnlockableContent{ return (hasItems && itemCapacity > 0); } + /** sets {@param out} to the index-th side outside of this block, using the given rotation. */ + public void nearbySide(int x, int y, int rotation, int index, Point2 out){ + int cornerX = x - (size-1)/2, cornerY = y - (size-1)/2, s = size; + switch(rotation){ + case 0 -> out.set(cornerX + s, cornerY + index); + case 1 -> out.set(cornerX + index, cornerY + s); + case 2 -> out.set(cornerX - 1, cornerY + index); + case 3 -> out.set(cornerX + index, cornerY - 1); + } + } + /** Iterate through ever grid position taken up by this block. */ public void iterateTaken(int x, int y, Intc2 placer){ if(isMultiblock()){ diff --git a/core/src/mindustry/world/blocks/heat/HeatBlock.java b/core/src/mindustry/world/blocks/heat/HeatBlock.java new file mode 100644 index 0000000000..da72507e18 --- /dev/null +++ b/core/src/mindustry/world/blocks/heat/HeatBlock.java @@ -0,0 +1,14 @@ +package mindustry.world.blocks.heat; + +/** Basic interface for any block that produces or requires heat.*/ +public interface HeatBlock{ + float heat(); + + //potentially unnecessary + /* + void heat(float value); + + default void addHeat(float amount){ + heat(heat() + amount); + }*/ +} diff --git a/core/src/mindustry/world/blocks/heat/HeatProducer.java b/core/src/mindustry/world/blocks/heat/HeatProducer.java new file mode 100644 index 0000000000..849ca04d64 --- /dev/null +++ b/core/src/mindustry/world/blocks/heat/HeatProducer.java @@ -0,0 +1,131 @@ +package mindustry.world.blocks.heat; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.util.*; +import arc.util.io.*; +import mindustry.annotations.Annotations.*; +import mindustry.entities.units.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.logic.*; +import mindustry.ui.*; +import mindustry.world.*; +import mindustry.world.blocks.power.NuclearReactor.*; +import mindustry.world.meta.*; + +public class HeatProducer extends Block{ + public float heatOutput = 10f; + public float warmupRate = 0.25f; + public float consumeTime = 100; + + public @Load("@-heat") TextureRegion heatRegion; + public @Load("@-glow") TextureRegion glowRegion; + public @Load("@-top1") TextureRegion topRegion1; + public @Load("@-top2") TextureRegion topRegion2; + public Color heatColor = new Color(1f, 0.22f, 0.22f, 0.8f); + public float heatPulse = 0.3f, heatPulseScl = 10f, glowMult = 1.2f; + + public HeatProducer(String name){ + super(name); + + update = solid = rotate = true; + canOverdrive = false; + } + + @Override + public void setStats(){ + stats.timePeriod = consumeTime; + super.setStats(); + stats.add(Stat.productionTime, consumeTime / 60f, StatUnit.seconds); + //TODO heat prod stats + } + + @Override + public void setBars(){ + super.setBars(); + + bars.add("heat", (NuclearReactorBuild entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat)); + } + + @Override + public void drawRequestRegion(BuildPlan req, Eachable list){ + Draw.rect(region, req.drawx(), req.drawy()); + Draw.rect(req.rotation > 1 ? topRegion2 : topRegion1, req.drawx(), req.drawy(), req.rotation * 90); + } + + + @Override + public TextureRegion[] icons(){ + return new TextureRegion[]{region, topRegion1}; + } + + public class HeatProducerBuild extends Building implements HeatBlock{ + public float heat; + public float progress; + + @Override + public void updateTile(){ + if(consValid()){ + progress += getProgressIncrease(consumeTime); + + if(progress >= 1f){ + consume(); + progress -= 1f; + } + } + + //heat approaches target at the same speed regardless of efficiency + heat = Mathf.approachDelta(heat, heatOutput * efficiency() * Mathf.num(consValid()), warmupRate * delta()); + } + + @Override + public void draw(){ + Draw.rect(region, x, y); + + Draw.rect(rotation > 1 ? topRegion2 : topRegion1, x, y, rotdeg()); + + if(heat > 0){ + Draw.z(Layer.blockAdditive); + Draw.blend(Blending.additive); + Draw.color(heatColor, heat / heatOutput * (heatColor.a * (1f - heatPulse + Mathf.absin(heatPulseScl, heatPulse)))); + Draw.rect(heatRegion, x, y, rotdeg()); + Draw.color(Draw.getColor().mul(glowMult)); + Draw.rect(glowRegion, x, y); + Draw.blend(); + Draw.color(); + } + } + + @Override + public double sense(LAccess sensor){ + if(sensor == LAccess.progress) return Mathf.clamp(progress); + return super.sense(sensor); + } + + @Override + public boolean shouldAmbientSound(){ + return cons.valid(); + } + + @Override + public float heat(){ + return heat; + } + + @Override + public void write(Writes write){ + super.write(write); + write.f(progress); + write.f(heat); + } + + @Override + public void read(Reads read, byte revision){ + super.read(read, revision); + progress = read.f(); + heat = read.f(); + } + } +} diff --git a/core/src/mindustry/world/blocks/production/BeamDrill.java b/core/src/mindustry/world/blocks/production/BeamDrill.java index 73af805a08..226b776137 100644 --- a/core/src/mindustry/world/blocks/production/BeamDrill.java +++ b/core/src/mindustry/world/blocks/production/BeamDrill.java @@ -83,7 +83,7 @@ public class BeamDrill extends Block{ int count = 0; for(int i = 0; i < size; i++){ - getLaserPos(x, y, rotation, i, Tmp.p1); + nearbySide(x, y, rotation, i, Tmp.p1); int j = 0; Item found = null; @@ -139,7 +139,7 @@ public class BeamDrill extends Block{ @Override public boolean canPlaceOn(Tile tile, Team team, int rotation){ for(int i = 0; i < size; i++){ - getLaserPos(tile.x, tile.y, rotation, i, Tmp.p1); + nearbySide(tile.x, tile.y, rotation, i, Tmp.p1); for(int j = 0; j < range; j++){ Tile other = world.tile(Tmp.p1.x + Geometry.d4x(rotation)*j, Tmp.p1.y + Geometry.d4y(rotation)*j); if(other != null && other.solid()){ @@ -155,16 +155,6 @@ public class BeamDrill extends Block{ return false; } - void getLaserPos(int tx, int ty, int rotation, int i, Point2 out){ - int cornerX = tx - (size-1)/2, cornerY = ty - (size-1)/2, s = size; - switch(rotation){ - case 0 -> out.set(cornerX + s, cornerY + i); - case 1 -> out.set(cornerX + i, cornerY + s); - case 2 -> out.set(cornerX - 1, cornerY + i); - case 3 -> out.set(cornerX + i, cornerY - 1); - } - } - public class BeamDrillBuild extends Building{ public Tile[] facing = new Tile[size]; public Point2[] lasers = new Point2[size]; @@ -306,7 +296,7 @@ public class BeamDrill extends Block{ void updateLasers(){ for(int i = 0; i < size; i++){ if(lasers[i] == null) lasers[i] = new Point2(); - getLaserPos(tileX(), tileY(), rotation, i, lasers[i]); + nearbySide(tileX(), tileY(), rotation, i, lasers[i]); } } diff --git a/gradle.properties b/gradle.properties index 41e4323054..e543381774 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=b0c234f0017ca4a7f28a70246e132e58401a7cde +archash=0531e7f883427a7c9a478a22b11a5d91cb1bab7b