Directional liquid bridge

This commit is contained in:
Anuken
2021-11-08 12:06:55 -05:00
parent ce0e26f008
commit dffe90acff
15 changed files with 315 additions and 208 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -431,3 +431,4 @@
63277=reinforced-liquid-container|block-reinforced-liquid-container-ui 63277=reinforced-liquid-container|block-reinforced-liquid-container-ui
63276=einforced-liquid-tank|block-einforced-liquid-tank-ui 63276=einforced-liquid-tank|block-einforced-liquid-tank-ui
63275=reinforced-liquid-tank|block-reinforced-liquid-tank-ui 63275=reinforced-liquid-tank|block-reinforced-liquid-tank-ui
63274=reinforced-bridge-conduit|block-reinforced-bridge-conduit-ui

Binary file not shown.

View File

@@ -31,6 +31,7 @@ public class GroundAI extends AIController{
if(state.rules.waves && unit.team == state.rules.defaultTeam){ if(state.rules.waves && unit.team == state.rules.defaultTeam){
Tile spawner = getClosestSpawner(); Tile spawner = getClosestSpawner();
if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)) move = false; if(spawner != null && unit.within(spawner, state.rules.dropZoneRadius + 120f)) move = false;
if(spawner == null && core == null) move = false;
} }
if(move) pathfind(Pathfinder.fieldCore); if(move) pathfind(Pathfinder.fieldCore);

View File

@@ -80,7 +80,7 @@ public class Blocks implements ContentList{
//liquid //liquid
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidContainer, liquidTank, liquidJunction, bridgeConduit, phaseConduit, mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidContainer, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
reinforcedConduit, reinforcedLiquidRouter, reinforcedLiquidContainer, reinforcedLiquidTank, reinforcedConduit, reinforcedBridgeConduit, reinforcedLiquidRouter, reinforcedLiquidContainer, reinforcedLiquidTank,
//power //power
combustionGenerator, thermalGenerator, steamGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor, combustionGenerator, thermalGenerator, steamGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor,
@@ -1433,10 +1433,16 @@ public class Blocks implements ContentList{
botColor = Pal.darkestMetal; botColor = Pal.darkestMetal;
leaks = true; leaks = true;
liquidCapacity = 20f; liquidCapacity = 20f;
liquidPressure = 1.1f; liquidPressure = 1.03f;
health = 250; health = 250;
}}; }};
reinforcedBridgeConduit = new DirectionLiquidBridge("reinforced-bridge-conduit"){{
requirements(Category.liquid, with(Items.graphite, 4, Items.beryllium, 8));
range = 4;
hasPower = false;
}};
reinforcedLiquidRouter = new LiquidRouter("reinforced-liquid-router"){{ reinforcedLiquidRouter = new LiquidRouter("reinforced-liquid-router"){{
requirements(Category.liquid, with(Items.graphite, 4, Items.beryllium, 2)); requirements(Category.liquid, with(Items.graphite, 4, Items.beryllium, 2));
liquidCapacity = 30f; liquidCapacity = 30f;
@@ -1454,7 +1460,6 @@ public class Blocks implements ContentList{
liquidCapacity = 2700f; liquidCapacity = 2700f;
}}; }};
//endregion //endregion
//region power //region power

View File

@@ -0,0 +1,225 @@
package mindustry.world.blocks.distribution;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
public class DirectionBridge extends Block{
private static BuildPlan otherReq;
private int otherDst = 0;
public @Load("@-bridge") TextureRegion bridgeRegion;
public @Load("@-bridge-bottom") TextureRegion bridgeBotRegion;
public @Load("@-bridge-liquid") TextureRegion bridgeLiquidRegion;
public @Load("@-arrow") TextureRegion arrowRegion;
public @Load("@-dir") TextureRegion dirRegion;
public int range = 4;
public DirectionBridge(String name){
super(name);
update = true;
solid = true;
rotate = true;
group = BlockGroup.transportation;
noUpdateDisabled = true;
envEnabled = Env.space | Env.terrestrial | Env.underwater;
drawArrow = false;
}
@Override
public void init(){
clipSize = Math.max(clipSize, (range + 0.5f) * 2 * tilesize);
super.init();
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(dirRegion, req.drawx(), req.drawy(), req.rotation * 90);
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
otherReq = null;
otherDst = range;
Point2 d = Geometry.d4(req.rotation);
list.each(other -> {
if(other.block == this && req != other && Mathf.clamp(other.x - req.x, -1, 1) == d.x && Mathf.clamp(other.y - req.y, -1, 1) == d.y){
int dst = Math.max(Math.abs(other.x - req.x), Math.abs(other.y - req.y));
if(dst <= otherDst){
otherReq = other;
otherDst = dst;
}
}
});
if(otherReq != null){
drawBridge(req.rotation, req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy(), null);
}
}
@Override
public TextureRegion[] icons(){
return new TextureRegion[]{region, dirRegion};
}
@Override
public void changePlacementPath(Seq<Point2> 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 void drawPlace(int x, int y, int rotation, boolean valid, boolean line){
int length = range;
Building found = null;
int dx = Geometry.d4x(rotation), dy = Geometry.d4y(rotation);
//find the link
for(int i = 1; i <= range; i++){
Tile other = world.tile(x + dx * i, y + dy * i);
if(other != null && other.build instanceof DirectionBridgeBuild build && build.block == this && build.team == player.team()){
length = i;
found = other.build;
break;
}
}
if(line || found != null){
Drawf.dashLine(Pal.placing,
x * tilesize + dx * (tilesize / 2f + 2),
y * tilesize + dy * (tilesize / 2f + 2),
x * tilesize + dx * (length) * tilesize,
y * tilesize + dy * (length) * tilesize
);
}
if(found != null){
if(line){
Drawf.square(found.x, found.y, found.block.size * tilesize/2f + 2.5f, 0f);
}else{
Drawf.square(found.x, found.y, 2f);
}
}
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
super.drawPlace(x, y, rotation, valid);
drawPlace(x, y, rotation, valid, true);
}
public void drawBridge(int rotation, float x1, float y1, float x2, float y2, @Nullable Color liquidColor){
Draw.alpha(Renderer.bridgeOpacity);
float
angle = Angles.angle(x1, y1, x2, y2),
cx = (x1 + x2)/2f,
cy = (y1 + y2)/2f,
len = Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)) - size * tilesize;
Draw.rect(bridgeRegion, cx, cy, len, tilesize, angle);
if(liquidColor != null){
Draw.color(liquidColor, liquidColor.a * Renderer.bridgeOpacity);
Draw.rect(bridgeLiquidRegion, cx, cy, len, tilesize, angle);
Draw.color();
Draw.alpha(Renderer.bridgeOpacity);
}
if(bridgeBotRegion.found()){
Draw.color(0.4f, 0.4f, 0.4f, 0.4f * Renderer.bridgeOpacity);
Draw.rect(bridgeBotRegion, cx, cy, len, tilesize, angle);
Draw.reset();
}
Draw.alpha(Renderer.bridgeOpacity);
for(float i = 6f; i <= len + size * tilesize - 5f; i += 5f){
Draw.rect(arrowRegion, x1 + Geometry.d4x(rotation) * i, y1 + Geometry.d4y(rotation) * i, angle);
}
Draw.reset();
}
public boolean positionsValid(int x1, int y1, int x2, int y2){
if(x1 == x2){
return Math.abs(y1 - y2) <= range;
}else if(y1 == y2){
return Math.abs(x1 - x2) <= range;
}else{
return false;
}
}
public class DirectionBridgeBuild extends Building{
public Building[] occupied = new Building[4];
@Override
public void draw(){
Draw.rect(block.region, x, y);
Draw.rect(dirRegion, x, y, rotdeg());
var link = findLink();
if(link != null){
Draw.z(Layer.power);
drawBridge(rotation, x, y, link.x, link.y, null);
}
}
@Override
public void drawSelect(){
drawPlace(tile.x, tile.y, rotation, true, false);
//draw incoming bridges
for(int dir = 0; dir < 4; dir++){
if(dir != rotation){
int dx = Geometry.d4x(dir), dy = Geometry.d4y(dir);
int length = range;
Building found = null;
//find the link
for(int i = 1; i <= range; i++){
Tile other = world.tile(tile.x + dx * i, tile.y + dy * i);
if(other != null && other.build instanceof DirectionBridgeBuild build && build.block == DirectionBridge.this && build.team == player.team() && (build.rotation + 2) % 4 == dir){
length = i;
found = other.build;
break;
}
}
if(found != null){
Drawf.dashLine(Pal.place,
found.x - dx * (tilesize / 2f + 2),
found.y - dy * (tilesize / 2f + 2),
found.x - dx * (length) * tilesize,
found.y - dy * (length) * tilesize
);
Drawf.square(found.x, found.y, 2f, 45f, Pal.place);
}
}
}
}
@Nullable
public DirectionBridgeBuild findLink(){
for(int i = 1; i <= range; i++){
Tile other = tile.nearby(Geometry.d4x(rotation) * i, Geometry.d4y(rotation) * i);
if(other != null && other.build instanceof DirectionBridgeBuild build && build.block == DirectionBridge.this && build.team == team){
return build;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,77 @@
package mindustry.world.blocks.distribution;
import arc.graphics.g2d.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.meta.*;
public class DirectionLiquidBridge extends DirectionBridge{
public final int timerFlow = timers++;
public float speed = 5f;
public @Load("@-liquid") TextureRegion liquidRegion;
public DirectionLiquidBridge(String name){
super(name);
outputsLiquid = true;
group = BlockGroup.liquids;
canOverdrive = false;
liquidCapacity = 20f;
hasLiquids = true;
}
public class DuctBridgeBuild extends DirectionBridgeBuild{
@Override
public void draw(){
Draw.rect(block.region, x, y);
if(liquids.total() > 0.001f){
Drawf.liquid(liquidRegion, x, y, liquids.total() / liquidCapacity, liquids.current().color);
}
Draw.rect(dirRegion, x, y, rotdeg());
var link = findLink();
if(link != null){
Draw.z(Layer.power);
drawBridge(rotation, x, y, link.x, link.y, Tmp.c1.set(liquids.current().color).a(liquids.currentAmount() / liquidCapacity));
}
}
@Override
public void updateTile(){
var link = findLink();
if(link != null){
moveLiquid(link, liquids.current());
link.occupied[rotation % 4] = this;
}
if(link == null){
if(liquids.total() > 0.0001f && timer(timerFlow, 1)){
moveLiquidForward(false, liquids.current());
}
}
for(int i = 0; i < 4; i++){
if(occupied[i] == null || occupied[i].rotation != i || !occupied[i].isValid()){
occupied[i] = null;
}
}
}
@Override
public boolean acceptLiquid(Building source, Liquid liquid){
int rel = this.relativeToEdge(source.tile);
return
hasLiquids && team == source.team &&
(liquids.current() == liquid || liquids.get(liquids.current()) < 0.2f) && rel != rotation &&
(occupied[(rel + 2) % 4] == null || occupied[(rel + 2) % 4] == source);
}
}
}

View File

@@ -1,223 +1,21 @@
package mindustry.world.blocks.distribution; package mindustry.world.blocks.distribution;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.*;
import mindustry.entities.units.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*; public class DuctBridge extends DirectionBridge{
public class DuctBridge extends Block{
private static BuildPlan otherReq;
private int otherDst = 0;
public @Load("@-bridge") TextureRegion bridgeRegion;
public @Load("@-bridge-bottom") TextureRegion bridgeBotRegion;
//public @Load("@-bridge-top") TextureRegion bridgeTopRegion;
public @Load("@-arrow") TextureRegion arrowRegion;
public @Load("@-dir") TextureRegion dirRegion;
public int range = 4;
public float speed = 5f; public float speed = 5f;
public DuctBridge(String name){ public DuctBridge(String name){
super(name); super(name);
update = true;
solid = true;
rotate = true;
itemCapacity = 4; itemCapacity = 4;
hasItems = true; hasItems = true;
group = BlockGroup.transportation;
noUpdateDisabled = true;
envEnabled = Env.space | Env.terrestrial | Env.underwater;
drawArrow = false;
} }
@Override public class DuctBridgeBuild extends DirectionBridgeBuild{
public void init(){
clipSize = Math.max(clipSize, (range + 0.5f) * 2 * tilesize);
super.init();
}
@Override
public void drawRequestRegion(BuildPlan req, Eachable<BuildPlan> list){
Draw.rect(region, req.drawx(), req.drawy());
Draw.rect(dirRegion, req.drawx(), req.drawy(), req.rotation * 90);
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
otherReq = null;
otherDst = range;
Point2 d = Geometry.d4(req.rotation);
list.each(other -> {
if(other.block == this && req != other && Mathf.clamp(other.x - req.x, -1, 1) == d.x && Mathf.clamp(other.y - req.y, -1, 1) == d.y){
int dst = Math.max(Math.abs(other.x - req.x), Math.abs(other.y - req.y));
if(dst <= otherDst){
otherReq = other;
otherDst = dst;
}
}
});
if(otherReq != null){
drawBridge(req.rotation, req.drawx(), req.drawy(), otherReq.drawx(), otherReq.drawy());
}
}
@Override
public TextureRegion[] icons(){
return new TextureRegion[]{region, dirRegion};
}
@Override
public void changePlacementPath(Seq<Point2> 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 void drawPlace(int x, int y, int rotation, boolean valid, boolean line){
int length = range;
Building found = null;
int dx = Geometry.d4x(rotation), dy = Geometry.d4y(rotation);
//find the link
for(int i = 1; i <= range; i++){
Tile other = world.tile(x + dx * i, y + dy * i);
if(other != null && other.build instanceof DuctBridgeBuild build && build.team == player.team()){
length = i;
found = other.build;
break;
}
}
if(line || found != null){
Drawf.dashLine(Pal.placing,
x * tilesize + dx * (tilesize / 2f + 2),
y * tilesize + dy * (tilesize / 2f + 2),
x * tilesize + dx * (length) * tilesize,
y * tilesize + dy * (length) * tilesize
);
}
if(found != null){
if(line){
Drawf.square(found.x, found.y, found.block.size * tilesize/2f + 2.5f, 0f);
}else{
Drawf.square(found.x, found.y, 2f);
}
}
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
super.drawPlace(x, y, rotation, valid);
drawPlace(x, y, rotation, valid, true);
}
public void drawBridge(int rotation, float x1, float y1, float x2, float y2){
Draw.alpha(Renderer.bridgeOpacity);
float
angle = Angles.angle(x1, y1, x2, y2),
cx = (x1 + x2)/2f,
cy = (y1 + y2)/2f,
len = Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)) - size * tilesize;
Draw.rect(bridgeRegion, cx, cy, len, tilesize, angle);
Draw.color(0.4f, 0.4f, 0.4f, 0.4f * Renderer.bridgeOpacity);
Draw.rect(bridgeBotRegion, cx, cy, len, tilesize, angle);
Draw.reset();
Draw.alpha(Renderer.bridgeOpacity);
for(float i = 6f; i <= len + size * tilesize - 5f; i += 5f){
Draw.rect(arrowRegion, x1 + Geometry.d4x(rotation) * i, y1 + Geometry.d4y(rotation) * i, angle);
}
Draw.reset();
}
public boolean positionsValid(int x1, int y1, int x2, int y2){
if(x1 == x2){
return Math.abs(y1 - y2) <= range;
}else if(y1 == y2){
return Math.abs(x1 - x2) <= range;
}else{
return false;
}
}
public class DuctBridgeBuild extends Building{
public Building[] occupied = new Building[4];
public float progress = 0f; public float progress = 0f;
@Override
public void draw(){
Draw.rect(block.region, x, y);
Draw.rect(dirRegion, x, y, rotdeg());
var link = findLink();
if(link != null){
Draw.z(Layer.power);
drawBridge(rotation, x, y, link.x, link.y);
}
}
@Override
public void drawSelect(){
drawPlace(tile.x, tile.y, rotation, true, false);
//draw incoming bridges
for(int dir = 0; dir < 4; dir++){
if(dir != rotation){
int dx = Geometry.d4x(dir), dy = Geometry.d4y(dir);
int length = range;
Building found = null;
//find the link
for(int i = 1; i <= range; i++){
Tile other = world.tile(tile.x + dx * i, tile.y + dy * i);
if(other != null && other.build instanceof DuctBridgeBuild build && build.team == player.team() && (build.rotation + 2) % 4 == dir){
length = i;
found = other.build;
break;
}
}
if(found != null){
Drawf.dashLine(Pal.place,
found.x - dx * (tilesize / 2f + 2),
found.y - dy * (tilesize / 2f + 2),
found.x - dx * (length) * tilesize,
found.y - dy * (length) * tilesize
);
Drawf.square(found.x, found.y, 2f, 45f, Pal.place);
}
}
}
}
@Nullable
public DuctBridgeBuild findLink(){
for(int i = 1; i <= range; i++){
Tile other = tile.nearby(Geometry.d4x(rotation) * i, Geometry.d4y(rotation) * i);
if(other != null && other.build instanceof DuctBridgeBuild build && build.team == team){
return build;
}
}
return null;
}
@Override @Override
public void updateTile(){ public void updateTile(){
var link = findLink(); var link = findLink();