From 58544e6a21163d146266978adb7641b28bfee4bc Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 28 Oct 2021 22:18:07 -0400 Subject: [PATCH] Beam nodes --- .../sprites/blocks/power/beam-node.png | Bin 0 -> 591 bytes core/assets/icons/icons.properties | 1 + core/assets/logicids.dat | Bin 2946 -> 2957 bytes core/src/mindustry/content/Blocks.java | 6 + core/src/mindustry/core/World.java | 8 + .../world/blocks/power/BeamNode.java | 171 ++++++++++++++++++ .../world/blocks/power/PowerNode.java | 9 +- 7 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/power/beam-node.png create mode 100644 core/src/mindustry/world/blocks/power/BeamNode.java diff --git a/core/assets-raw/sprites/blocks/power/beam-node.png b/core/assets-raw/sprites/blocks/power/beam-node.png new file mode 100644 index 0000000000000000000000000000000000000000..0941fd74dd1198d163ebf63ce8b711eae3f39ee6 GIT binary patch literal 591 zcmeAS@N?(olHy`uVBq!ia0y~yU{C^K4mJh`1}k^&LktWIjKx9jP7LeL$-HD>VB++2 zaSVxQJvx1TK9ixy@%`6zBzUT(NjIg;oO$Sxnd`I#7g(6X4ySB4@?^hW~UyNk+(0QDy7-HZka7f-wy|Kl3+U+?yUIKi|f5clj(_g;K zPL#O0c;C@?{*_xx#s^r3;hJ^WAbhm+st=zPxy6W->mPA z$8WPgUZl6^lX2Z*306jj?3qRi4gW73(C9Eq^f7;Tk5a=8i`+=1>AadJR24%E-b4u) z^^~8JICNBP+J;+>@7Je3kq%z8Mo0SO#Q=j;HCwJW^}W*f0;~-bf4)@k`PqJnH{Hi# zS&pvvwKcAaJ_ZfDQbKNN-&yD1bfI_YtFTMmDKnIwHgxx0n`?PS)0Fc%@AmAL+oqA5 zpUFjN8H)O=P0U~Vr$hQnwWsZ;uRjAVUaxz`ecm)XUH9<){fAhrPOn&_#JpnB7QKWt z-U+umb$L=-b$WDLgpRNsD-l_nr(V{`&|t5T&idh&hnhMA0|SGntDnm{r-UW|LnsN2 literal 0 HcmV?d00001 diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 546ce9b5bd..c27eea40b4 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -412,3 +412,4 @@ 63296=steam-vent|block-steam-vent-ui 63295=pressure-turbine|block-pressure-turbine-ui 63294=turbine-condenser|block-turbine-condenser-ui +63293=beam-node|block-beam-node-ui diff --git a/core/assets/logicids.dat b/core/assets/logicids.dat index 08bb6ff5b8106fb6168d11c519a917f58e48ba10..b257033c7198f59ff3a0f4e4f96a001456f2ef07 100644 GIT binary patch delta 27 icmZn??-gfaSiX@djgyNrDK#-yH!nXWb#pqWG!p=9GY7-~ delta 16 XcmeAbZxUx>ShkTVjdOD`rxX(aC;0?Z diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 2680c2575e..ded62b4213 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -79,6 +79,7 @@ public class Blocks implements ContentList{ combustionGenerator, thermalGenerator, steamGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor, turbineCondenser, impactReactor, battery, batteryLarge, powerNode, powerNodeLarge, surgeTower, diode, + beamNode, //production mechanicalDrill, pneumaticDrill, laserDrill, blastDrill, waterExtractor, oilExtractor, cultivator, @@ -1401,6 +1402,11 @@ public class Blocks implements ContentList{ baseExplosiveness = 5f; }}; + beamNode = new BeamNode("beam-node"){{ + requirements(Category.power, with(Items.graphite, 1, Items.lead, 3)); + range = 10; + }}; + combustionGenerator = new BurnerGenerator("combustion-generator"){{ requirements(Category.power, with(Items.copper, 25, Items.lead, 15)); powerProduction = 1f; diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index 47d4c05475..f7105429a4 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -31,12 +31,20 @@ public class World{ public final Context context = new Context(); public Tiles tiles = new Tiles(0, 0); + /** The number of times tiles have changed in this session. Used for blocks that need to poll world state, but not frequently. */ + public int tileChanges = -1; private boolean generating, invalidMap; private ObjectMap customMapLoaders = new ObjectMap<>(); public World(){ + Events.on(TileChangeEvent.class, e -> { + tileChanges ++; + }); + Events.on(WorldLoadEvent.class, e -> { + tileChanges = -1; + }); } /** Adds a custom handler function for loading a custom map - usually a generated one. */ diff --git a/core/src/mindustry/world/blocks/power/BeamNode.java b/core/src/mindustry/world/blocks/power/BeamNode.java new file mode 100644 index 0000000000..32f5461556 --- /dev/null +++ b/core/src/mindustry/world/blocks/power/BeamNode.java @@ -0,0 +1,171 @@ +package mindustry.world.blocks.power; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.math.geom.*; +import arc.struct.*; +import mindustry.*; +import mindustry.annotations.Annotations.*; +import mindustry.core.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.input.*; +import mindustry.world.*; +import mindustry.world.meta.*; + +import java.util.*; + +import static mindustry.Vars.*; + +public class BeamNode extends PowerBlock{ + public int range = 5; + + public @Load("power-beam") TextureRegion laser; + public @Load("power-beam-end") TextureRegion laserEnd; + + public Color laserColor1 = Color.white; + public Color laserColor2 = Color.valueOf("ffd9c2"); + public float pulseScl = 7, pulseMag = 0.05f; + public float laserWidth = 0.4f; + + public BeamNode(String name){ + super(name); + consumesPower = outputsPower = false; + drawDisabled = false; + envEnabled |= Env.space; + } + + @Override + public void init(){ + super.init(); + + clipSize = Math.max(clipSize, tilesize*size + (range+1)*tilesize*2); + } + + @Override + public void drawPlace(int x, int y, int rotation, boolean valid){ + for(int i = 0; i < 4; i++){ + int maxLen = range; + Building dest = null; + var dir = Geometry.d4[i]; + int dx = dir.x, dy = dir.y; + for(int j = 1; j <= range; j++){ + var other = world.build(x + j * dir.x, y + j * dir.y); + if(other != null && other.block.hasPower && other.team == Vars.player.team()){ + maxLen = j; + dest = other; + break; + } + } + + Drawf.dashLine(Pal.placing, + x * tilesize + dx * (tilesize / 2f + 2), + y * tilesize + dy * (tilesize / 2f + 2), + x * tilesize + dx * (maxLen) * tilesize, + y * tilesize + dy * (maxLen) * tilesize + ); + + if(dest != null){ + Drawf.square(dest.x, dest.y, dest.block.size * tilesize/2f + 2.5f, 0f); + } + } + } + + @Override + public void changePlacementPath(Seq points, int rotation){ + Placement.calculateNodes(points, this, rotation, (point, other) -> Math.max(Math.abs(point.x - other.x), Math.abs(point.y - other.y)) <= range); + } + + public class BeamNodeBuild extends Building{ + //current links in cardinal directions + public Building[] links = new Building[4]; + public Tile[] dests = new Tile[4]; + public int lastChange = -2; + + @Override + public void updateTile(){ + if(lastChange != world.tileChanges){ + lastChange = world.tileChanges; + updateDirections(); + } + } + + @Override + public void draw(){ + super.draw(); + + if(Mathf.zero(Renderer.laserOpacity)) return; + + Draw.z(Layer.power); + Draw.color(laserColor1, laserColor2, (1f - power.graph.getSatisfaction()) * 0.86f + Mathf.absin(3f, 0.1f)); + Draw.alpha(Renderer.laserOpacity); + float w = laserWidth + Mathf.absin(pulseScl, pulseMag); + + for(int i = 0; i < 4; i ++){ + if(dests[i] != null && (links[i].block != block || links[i].id > id)){ + int dst = Math.max(Math.abs(dests[i].x - tile.x), Math.abs(dests[i].y - tile.y)); + //don't draw lasers for adjacent blocks + if(dst > 1){ + var point = Geometry.d4[i]; + float poff = tilesize/2f; + Drawf.laser(team, laser, laserEnd, x + poff*point.x, y + poff*point.y, dests[i].worldx() - poff*point.x, dests[i].worldy() - poff*point.y, w); + } + } + } + + Draw.reset(); + } + + @Override + public void pickedUp(){ + Arrays.fill(links, null); + Arrays.fill(dests, null); + } + + public void updateDirections(){ + for(int i = 0; i < 4; i ++){ + var prev = links[i]; + var dir = Geometry.d4[i]; + links[i] = null; + dests[i] = null; + //find first block with power in range + for(int j = 1; j <= range; j++){ + var other = world.build(tile.x + j * dir.x, tile.y + j * dir.y); + if(other != null && other.block.hasPower && other.team == team){ + links[i] = other; + dests[i] = world.tile(tile.x + j * dir.x, tile.y + j * dir.y); + break; + } + } + + var next = links[i]; + + if(next != prev){ + //unlinked, disconnect and reflow + if(prev != null){ + prev.power.links.removeValue(pos()); + + PowerGraph newgraph = new PowerGraph(); + //reflow from this point, covering all tiles on this side + newgraph.reflow(this); + + if(prev.power.graph != newgraph){ + //reflow power for other end + PowerGraph og = new PowerGraph(); + og.reflow(prev); + } + } + + //linked to a new one, connect graphs + if(next != null){ + power.links.addUnique(next.pos()); + next.power.links.addUnique(pos()); + + power.graph.addGraph(next.power.graph); + } + } + } + } + } +} diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 4c59a84174..cbd378284b 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -68,15 +68,10 @@ public class PowerNode extends PowerBlock{ } }else if(linkValid(entity, other) && valid && power.links.size < maxNodes){ - if(!power.links.contains(other.pos())){ - power.links.add(other.pos()); - } + power.links.addUnique(other.pos()); if(other.team == entity.team){ - - if(!other.power.links.contains(entity.pos())){ - other.power.links.add(entity.pos()); - } + other.power.links.addUnique(entity.pos()); } power.graph.addGraph(other.power.graph);