Tileable displays nobody asked for
This commit is contained in:
@@ -592,3 +592,4 @@
|
|||||||
63090=remove-ore|block-remove-ore-ui
|
63090=remove-ore|block-remove-ore-ui
|
||||||
63089=small-heat-redirector|block-small-heat-redirector-ui
|
63089=small-heat-redirector|block-small-heat-redirector-ui
|
||||||
63088=large-cliff-crusher|block-large-cliff-crusher-ui
|
63088=large-cliff-crusher|block-large-cliff-crusher-ui
|
||||||
|
63087=tile-logic-display|block-tile-logic-display-ui
|
||||||
|
|||||||
Binary file not shown.
@@ -158,7 +158,7 @@ public class Blocks{
|
|||||||
payloadConveyor, payloadRouter, reinforcedPayloadConveyor, reinforcedPayloadRouter, payloadMassDriver, largePayloadMassDriver, smallDeconstructor, deconstructor, constructor, largeConstructor, payloadLoader, payloadUnloader,
|
payloadConveyor, payloadRouter, reinforcedPayloadConveyor, reinforcedPayloadRouter, payloadMassDriver, largePayloadMassDriver, smallDeconstructor, deconstructor, constructor, largeConstructor, payloadLoader, payloadUnloader,
|
||||||
|
|
||||||
//logic
|
//logic
|
||||||
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
|
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, logicDisplayTile, memoryCell, memoryBank,
|
||||||
canvas, reinforcedMessage,
|
canvas, reinforcedMessage,
|
||||||
worldProcessor, worldCell, worldMessage, worldSwitch,
|
worldProcessor, worldCell, worldMessage, worldSwitch,
|
||||||
|
|
||||||
@@ -6066,6 +6066,10 @@ public class Blocks{
|
|||||||
size = 6;
|
size = 6;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
logicDisplayTile = new TileableLogicDisplay("tile-logic-display"){{
|
||||||
|
requirements(Category.logic, with(Items.lead, 10, Items.silicon, 10, Items.metaglass, 10, Items.phaseFabric, 6));
|
||||||
|
}};
|
||||||
|
|
||||||
canvas = new CanvasBlock("canvas"){{
|
canvas = new CanvasBlock("canvas"){{
|
||||||
requirements(Category.logic, BuildVisibility.shown, with(Items.silicon, 10, Items.beryllium, 10));
|
requirements(Category.logic, BuildVisibility.shown, with(Items.silicon, 10, Items.beryllium, 10));
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ public class LExecutor{
|
|||||||
public LInstruction[] instructions = {};
|
public LInstruction[] instructions = {};
|
||||||
/** Non-constant variables used for network sync */
|
/** Non-constant variables used for network sync */
|
||||||
public LVar[] vars = {};
|
public LVar[] vars = {};
|
||||||
|
|
||||||
public LVar counter, unit, thisv, ipt;
|
public LVar counter, unit, thisv, ipt;
|
||||||
|
|
||||||
public int[] binds;
|
public int[] binds;
|
||||||
public boolean yield;
|
public boolean yield;
|
||||||
|
|
||||||
@@ -226,8 +226,8 @@ public class LExecutor{
|
|||||||
cache.found = false;
|
cache.found = false;
|
||||||
outFound.setnum(0);
|
outFound.setnum(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res != null && res.build != null &&
|
if(res != null && res.build != null &&
|
||||||
(unit.within(res.build.x, res.build.y, Math.max(unit.range(), buildingRange)) || res.build.team == exec.team)){
|
(unit.within(res.build.x, res.build.y, Math.max(unit.range(), buildingRange)) || res.build.team == exec.team)){
|
||||||
cache.build = res.build;
|
cache.build = res.build;
|
||||||
outBuild.setobj(res.build);
|
outBuild.setobj(res.build);
|
||||||
@@ -935,11 +935,7 @@ public class LExecutor{
|
|||||||
if(Vars.headless) return;
|
if(Vars.headless) return;
|
||||||
|
|
||||||
if(target.building() instanceof LogicDisplayBuild d && (d.team == exec.team || exec.privileged)){
|
if(target.building() instanceof LogicDisplayBuild d && (d.team == exec.team || exec.privileged)){
|
||||||
if(d.commands.size + exec.graphicsBuffer.size < maxDisplayBuffer){
|
d.flushCommands(exec.graphicsBuffer);
|
||||||
for(int i = 0; i < exec.graphicsBuffer.size; i++){
|
|
||||||
d.commands.addLast(exec.graphicsBuffer.items[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exec.graphicsBuffer.clear();
|
exec.graphicsBuffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1939,7 +1935,7 @@ public class LExecutor{
|
|||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
Sound sound = Sounds.getSound(id.numi());
|
Sound sound = Sounds.getSound(id.numi());
|
||||||
if(sound == null || sound == Sounds.swish) sound = Sounds.none; //no.
|
if(sound == null || sound == Sounds.swish) sound = Sounds.none; //no.
|
||||||
|
|
||||||
if(positional){
|
if(positional){
|
||||||
sound.at(World.unconv(x.numf()), World.unconv(y.numf()), pitch.numf(), Math.min(volume.numf(), 2f), limit.bool());
|
sound.at(World.unconv(x.numf()), World.unconv(y.numf()), pitch.numf(), Math.min(volume.numf(), 2f), limit.bool());
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import mindustry.annotations.Annotations.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
@@ -65,7 +66,7 @@ public class LogicDisplay extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class LogicDisplayBuild extends Building{
|
public class LogicDisplayBuild extends Building{
|
||||||
public FrameBuffer buffer;
|
public @Nullable FrameBuffer buffer;
|
||||||
public float color = Color.whiteFloatBits;
|
public float color = Color.whiteFloatBits;
|
||||||
public float stroke = 1f;
|
public float stroke = 1f;
|
||||||
public LongQueue commands = new LongQueue(256);
|
public LongQueue commands = new LongQueue(256);
|
||||||
@@ -87,12 +88,32 @@ public class LogicDisplay extends Block{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
processCommands();
|
||||||
|
|
||||||
|
Draw.blend(Blending.disabled);
|
||||||
|
Draw.draw(Draw.z(), () -> {
|
||||||
|
if(buffer != null){
|
||||||
|
Draw.rect(Draw.wrap(buffer.getTexture()), x, y, buffer.getWidth() * scaleFactor * Draw.scl, -buffer.getHeight() * scaleFactor * Draw.scl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Draw.blend();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flushCommands(LongSeq graphicsBuffer){
|
||||||
|
int added = Math.min(graphicsBuffer.size, LExecutor.maxDisplayBuffer - commands.size);
|
||||||
|
|
||||||
|
for(int i = 0; i < added; i++){
|
||||||
|
commands.addLast(graphicsBuffer.items[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processCommands(){
|
||||||
//don't bother processing commands if displays are off
|
//don't bother processing commands if displays are off
|
||||||
if(!commands.isEmpty()){
|
if(!commands.isEmpty() && buffer != null){
|
||||||
Draw.draw(Draw.z(), () -> {
|
Draw.draw(Draw.z(), () -> {
|
||||||
Tmp.m1.set(Draw.proj());
|
Tmp.m1.set(Draw.proj());
|
||||||
Tmp.m2.set(Draw.trans());
|
Tmp.m2.set(Draw.trans());
|
||||||
Draw.proj(0, 0, displaySize, displaySize);
|
Draw.proj(0, 0, buffer.getWidth(), buffer.getHeight());
|
||||||
if(transform != null){
|
if(transform != null){
|
||||||
Draw.trans(transform);
|
Draw.trans(transform);
|
||||||
}
|
}
|
||||||
@@ -148,14 +169,6 @@ public class LogicDisplay extends Block{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.blend(Blending.disabled);
|
|
||||||
Draw.draw(Draw.z(), () -> {
|
|
||||||
if(buffer != null){
|
|
||||||
Draw.rect(Draw.wrap(buffer.getTexture()), x, y, buffer.getWidth() * scaleFactor * Draw.scl, -buffer.getHeight() * scaleFactor * Draw.scl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Draw.blend();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
149
core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java
Normal file
149
core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
package mindustry.world.blocks.logic;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.gl.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
public class TileableLogicDisplay extends LogicDisplay{
|
||||||
|
protected static final Seq<TileableLogicDisplayBuild> queue = new Seq<>();
|
||||||
|
protected static final Seq<TileableLogicDisplayBuild> displays = new Seq<>();
|
||||||
|
protected static final IntSet processed = new IntSet();
|
||||||
|
|
||||||
|
public TileableLogicDisplay(String name){
|
||||||
|
super(name);
|
||||||
|
|
||||||
|
displaySize = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void linkDisplays(TileableLogicDisplayBuild start){
|
||||||
|
TileableLogicDisplayBuild root = null;
|
||||||
|
|
||||||
|
int topX = start.tile.x, topY = start.tile.y, botX = start.tile.x, botY = start.tile.y;
|
||||||
|
|
||||||
|
queue.clear();
|
||||||
|
displays.clear();
|
||||||
|
processed.clear();
|
||||||
|
|
||||||
|
queue.add(start);
|
||||||
|
displays.add(start);
|
||||||
|
|
||||||
|
while(!queue.isEmpty()){
|
||||||
|
var next = queue.pop();
|
||||||
|
processed.add(next.id);
|
||||||
|
|
||||||
|
//assign root based on bottom leftmost position
|
||||||
|
if(root == null || next.tile.x < root.tile.x || next.tile.y < root.tile.y){
|
||||||
|
root = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
topX = Math.max(next.tile.x, topX);
|
||||||
|
topY = Math.max(next.tile.y, topY);
|
||||||
|
botX = Math.min(next.tile.x, botX);
|
||||||
|
botY = Math.min(next.tile.y, botY);
|
||||||
|
|
||||||
|
for(var prox : next.proximity){
|
||||||
|
if(prox instanceof TileableLogicDisplayBuild disp && processed.add(disp.id)){
|
||||||
|
queue.add(disp);
|
||||||
|
displays.add(disp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tilesWidth = topX - botX + 1, tilesHeight = topY - botY + 1;
|
||||||
|
|
||||||
|
//the new root display has been assigned
|
||||||
|
for(var member : displays){
|
||||||
|
member.rootDisplay = root;
|
||||||
|
member.tilesWidth = tilesWidth;
|
||||||
|
member.tilesHeight = tilesHeight;
|
||||||
|
member.originX = botX;
|
||||||
|
member.originY = botY;
|
||||||
|
|
||||||
|
//TODO: preserve buffers later
|
||||||
|
if(member.buffer != null){
|
||||||
|
member.buffer.dispose();
|
||||||
|
member.buffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TileableLogicDisplayBuild extends LogicDisplayBuild{
|
||||||
|
//bottom left corner of display
|
||||||
|
public TileableLogicDisplayBuild rootDisplay = this;
|
||||||
|
//size of display area
|
||||||
|
public int tilesWidth = 1, tilesHeight = 1, originX, originY;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
Draw.rect(block.region, x, y);
|
||||||
|
|
||||||
|
//don't even bother processing anything when displays are off.
|
||||||
|
if(!Vars.renderer.drawDisplays) return;
|
||||||
|
|
||||||
|
if(isRoot()){
|
||||||
|
Draw.draw(Draw.z(), () -> {
|
||||||
|
if(buffer == null){
|
||||||
|
buffer = new FrameBuffer(32 * tilesWidth, 32 * tilesHeight);
|
||||||
|
Log.info("create " + buffer.getWidth() + " " + buffer.getHeight());
|
||||||
|
//clear the buffer - some OSs leave garbage in it
|
||||||
|
buffer.begin(Pal.darkerMetal);
|
||||||
|
buffer.end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
processCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.blend(Blending.disabled);
|
||||||
|
Draw.draw(Draw.z(), () -> {
|
||||||
|
if(rootDisplay.buffer != null){
|
||||||
|
|
||||||
|
int rtx = (tile.x - originX), rty = (tile.y - originY);
|
||||||
|
|
||||||
|
Tmp.tr1.set(rootDisplay.buffer.getTexture(), rtx * 32, rty * 32, 32, 32);
|
||||||
|
Draw.rect(Tmp.tr1, x, y, tilesize, -tilesize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Draw.blend();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushCommands(LongSeq graphicsBuffer){
|
||||||
|
if(isRoot()){
|
||||||
|
super.flushCommands(graphicsBuffer);
|
||||||
|
}else{
|
||||||
|
rootDisplay.flushCommands(graphicsBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProximityAdded(){
|
||||||
|
super.onProximityAdded();
|
||||||
|
|
||||||
|
linkDisplays(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProximityRemoved(){
|
||||||
|
super.onProximityRemoved();
|
||||||
|
|
||||||
|
processed.clear();
|
||||||
|
|
||||||
|
for(var other : proximity){
|
||||||
|
if(other instanceof TileableLogicDisplayBuild tl && !processed.contains(tl.id)){
|
||||||
|
linkDisplays(tl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRoot(){
|
||||||
|
return rootDisplay == this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user