Added large canvas block & canvas image export/import
This commit is contained in:
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-corner1.png
Normal file
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-corner1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 B |
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-corner2.png
Normal file
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-corner2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 195 B |
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-side1.png
Normal file
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-side1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 450 B |
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-side2.png
Normal file
BIN
core/assets-raw/sprites/blocks/logic/large-canvas-side2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 480 B |
BIN
core/assets-raw/sprites/blocks/logic/large-canvas.png
Normal file
BIN
core/assets-raw/sprites/blocks/logic/large-canvas.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 717 B |
@@ -125,6 +125,8 @@ maps.none = [lightgray]No maps found!
|
|||||||
invalid = Invalid
|
invalid = Invalid
|
||||||
pickcolor = Pick Color
|
pickcolor = Pick Color
|
||||||
color = Color
|
color = Color
|
||||||
|
import = Import
|
||||||
|
export = Export
|
||||||
preparingconfig = Preparing Config
|
preparingconfig = Preparing Config
|
||||||
preparingcontent = Preparing Content
|
preparingcontent = Preparing Content
|
||||||
uploadingcontent = Uploading Content
|
uploadingcontent = Uploading Content
|
||||||
@@ -2068,6 +2070,7 @@ block.reinforced-payload-router.name = Reinforced Payload Router
|
|||||||
block.payload-mass-driver.name = Payload Mass Driver
|
block.payload-mass-driver.name = Payload Mass Driver
|
||||||
block.small-deconstructor.name = Deconstructor
|
block.small-deconstructor.name = Deconstructor
|
||||||
block.canvas.name = Canvas
|
block.canvas.name = Canvas
|
||||||
|
block.large-canvas.name = Large Canvas
|
||||||
block.world-processor.name = World Processor
|
block.world-processor.name = World Processor
|
||||||
block.world-cell.name = World Cell
|
block.world-cell.name = World Cell
|
||||||
block.tank-fabricator.name = Tank Fabricator
|
block.tank-fabricator.name = Tank Fabricator
|
||||||
@@ -2527,6 +2530,7 @@ block.unit-repair-tower.description = Repairs all units in its vicinity. Require
|
|||||||
block.radar.description = Gradually uncovers terrain and enemy units in a large radius. Requires power.
|
block.radar.description = Gradually uncovers terrain and enemy units in a large radius. Requires power.
|
||||||
block.shockwave-tower.description = Damages and destroys enemy projectiles in a radius. Requires cyanogen.
|
block.shockwave-tower.description = Damages and destroys enemy projectiles in a radius. Requires cyanogen.
|
||||||
block.canvas.description = Displays a simple image with a pre-defined palette. Editable.
|
block.canvas.description = Displays a simple image with a pre-defined palette. Editable.
|
||||||
|
block.large-canvas.description = Displays a simple image with a pre-defined palette. Editable.
|
||||||
|
|
||||||
unit.dagger.description = Fires standard bullets at enemy targets.
|
unit.dagger.description = Fires standard bullets at enemy targets.
|
||||||
unit.mace.description = Fires streams of flame at enemy targets.
|
unit.mace.description = Fires streams of flame at enemy targets.
|
||||||
|
|||||||
@@ -623,3 +623,4 @@
|
|||||||
63059=metal-tiles-13|block-metal-tiles-13-ui
|
63059=metal-tiles-13|block-metal-tiles-13-ui
|
||||||
63058=metal-wall-3|block-metal-wall-3-ui
|
63058=metal-wall-3|block-metal-wall-3-ui
|
||||||
63057=ore-wall-graphite|block-ore-wall-graphite-ui
|
63057=ore-wall-graphite|block-ore-wall-graphite-ui
|
||||||
|
63056=large-canvas|block-large-canvas-ui
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -176,7 +176,7 @@ public class Blocks{
|
|||||||
|
|
||||||
//logic
|
//logic
|
||||||
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, tileLogicDisplay, memoryCell, memoryBank,
|
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, tileLogicDisplay, memoryCell, memoryBank,
|
||||||
canvas, reinforcedMessage,
|
canvas, largeCanvas, reinforcedMessage,
|
||||||
worldProcessor, worldCell, worldMessage, worldSwitch,
|
worldProcessor, worldCell, worldMessage, worldSwitch,
|
||||||
|
|
||||||
//campaign
|
//campaign
|
||||||
@@ -6882,6 +6882,35 @@ public class Blocks{
|
|||||||
size = 2;
|
size = 2;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
largeCanvas = new CanvasBlock("large-canvas"){{
|
||||||
|
requirements(Category.logic, BuildVisibility.shown, with(Items.silicon, 15, Items.beryllium, 15, Items.tungsten, 10));
|
||||||
|
|
||||||
|
canvasSize = 24;
|
||||||
|
padding = 7f / 4f * 2f;
|
||||||
|
|
||||||
|
size = 3;
|
||||||
|
|
||||||
|
//Palette: https://lospec.com/palette-list/woodspark
|
||||||
|
setPaletteFromString("""
|
||||||
|
452b3f
|
||||||
|
8a5865
|
||||||
|
e08d51
|
||||||
|
fabf61
|
||||||
|
f5eeb0
|
||||||
|
2c5e3b
|
||||||
|
609c4f
|
||||||
|
c6cc54
|
||||||
|
78c2d6
|
||||||
|
5479b0
|
||||||
|
56546e
|
||||||
|
839fa6
|
||||||
|
e0d3c8
|
||||||
|
f05b5b
|
||||||
|
8f325f
|
||||||
|
eb6c98
|
||||||
|
""");
|
||||||
|
}};
|
||||||
|
|
||||||
reinforcedMessage = new MessageBlock("reinforced-message"){{
|
reinforcedMessage = new MessageBlock("reinforced-message"){{
|
||||||
requirements(Category.logic, with(Items.graphite, 10, Items.beryllium, 5));
|
requirements(Category.logic, with(Items.graphite, 10, Items.beryllium, 5));
|
||||||
health = 100;
|
health = 100;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.files.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.input.*;
|
import arc.input.*;
|
||||||
@@ -23,22 +24,28 @@ public class CanvasEditDialog extends BaseDialog{
|
|||||||
static final float refreshTime = 60f * 2f;
|
static final float refreshTime = 60f * 2f;
|
||||||
|
|
||||||
int curColor;
|
int curColor;
|
||||||
boolean fill, modified;
|
boolean fill, modified, grid = true;
|
||||||
float time;
|
float time;
|
||||||
CanvasBuild canvas;
|
CanvasBuild canvas;
|
||||||
|
CanvasBlock block;
|
||||||
Pixmap pix;
|
Pixmap pix;
|
||||||
|
Texture texture;
|
||||||
|
|
||||||
public CanvasEditDialog(CanvasBuild canvas){
|
public CanvasEditDialog(CanvasBuild canvas){
|
||||||
super("");
|
super("");
|
||||||
titleTable.remove();
|
titleTable.remove();
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
CanvasBlock block = (CanvasBlock)canvas.block;
|
block = (CanvasBlock)canvas.block;
|
||||||
int size = block.canvasSize;
|
int size = block.canvasSize;
|
||||||
pix = block.makePixmap(canvas.data, new Pixmap(size, size));
|
pix = block.makePixmap(canvas.data, new Pixmap(size, size));
|
||||||
Texture texture = new Texture(pix);
|
texture = new Texture(pix);
|
||||||
curColor = block.palette[0];
|
curColor = block.palette[0];
|
||||||
|
|
||||||
addCloseButton();
|
addCloseButton(160f);
|
||||||
|
|
||||||
|
buttons.button("@import", Icon.image, () -> platform.showFileChooser(true, "png", this::importFrom));
|
||||||
|
|
||||||
|
buttons.button("@export", Icon.export, () -> platform.showFileChooser(false, "png", this::exportTo));
|
||||||
|
|
||||||
hidden(() -> {
|
hidden(() -> {
|
||||||
save();
|
save();
|
||||||
@@ -138,7 +145,7 @@ public class CanvasEditDialog extends BaseDialog{
|
|||||||
Draw.rect(Tmp.tr1, x + width/2f, y + height/2f, width, height);
|
Draw.rect(Tmp.tr1, x + width/2f, y + height/2f, width, height);
|
||||||
|
|
||||||
//draw grid
|
//draw grid
|
||||||
{
|
if(grid){
|
||||||
float xspace = (getWidth() / size);
|
float xspace = (getWidth() / size);
|
||||||
float yspace = (getHeight() / size);
|
float yspace = (getHeight() / size);
|
||||||
float s = 1f;
|
float s = 1f;
|
||||||
@@ -175,12 +182,18 @@ public class CanvasEditDialog extends BaseDialog{
|
|||||||
|
|
||||||
cont.row();
|
cont.row();
|
||||||
|
|
||||||
cont.add().size(60f);
|
cont.table(Tex.button, t -> {
|
||||||
|
t.button(Icon.grid, Styles.clearNoneTogglei, () -> grid = !grid).checked(grid).size(44f);
|
||||||
|
});
|
||||||
|
|
||||||
cont.table(Tex.button, p -> {
|
cont.table(Tex.button, p -> {
|
||||||
for(int i = 0; i < block.palette.length; i++){
|
for(int i = 0; i < block.palette.length; i++){
|
||||||
int fi = i;
|
int fi = i;
|
||||||
|
|
||||||
|
if(i % 8 == 0){
|
||||||
|
p.row();
|
||||||
|
}
|
||||||
|
|
||||||
var button = p.button(Tex.whiteui, Styles.squareTogglei, 30, () -> {
|
var button = p.button(Tex.whiteui, Styles.squareTogglei, 30, () -> {
|
||||||
curColor = block.palette[fi];
|
curColor = block.palette[fi];
|
||||||
}).size(44).checked(b -> curColor == block.palette[fi]).get();
|
}).size(44).checked(b -> curColor == block.palette[fi]).get();
|
||||||
@@ -192,11 +205,69 @@ public class CanvasEditDialog extends BaseDialog{
|
|||||||
t.button(Icon.fill, Styles.clearNoneTogglei, () -> fill = !fill).size(44f);
|
t.button(Icon.fill, Styles.clearNoneTogglei, () -> fill = !fill).size(44f);
|
||||||
});
|
});
|
||||||
|
|
||||||
closeOnBack();
|
|
||||||
|
|
||||||
buttons.defaults().size(150f, 64f);
|
buttons.defaults().size(150f, 64f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exportTo(Fi file){
|
||||||
|
try{
|
||||||
|
file.writePng(pix);
|
||||||
|
}catch(Exception e){
|
||||||
|
ui.showException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void importFrom(Fi file){
|
||||||
|
try{
|
||||||
|
Pixmap source = new Pixmap(file);
|
||||||
|
int size = pix.width;
|
||||||
|
if(source.width > size || source.height > size){
|
||||||
|
float ratio = (float)Math.max(source.width, source.height) / size;
|
||||||
|
Pixmap dest = new Pixmap(size, size);
|
||||||
|
dest.draw(source, 0, 0, source.width, source.height, (size - (int)(source.width / ratio))/2, (size - (int)(source.height / ratio))/2, (int)(source.width / ratio), (int)(source.height / ratio));
|
||||||
|
source.dispose();
|
||||||
|
source = dest;
|
||||||
|
}else if(source.width < size || source.height < size){
|
||||||
|
pix.fill(block.palette[0]);
|
||||||
|
Pixmap dest = new Pixmap(size, size);
|
||||||
|
dest.draw(source, (size - source.width)/2, (size - source.height)/2);
|
||||||
|
source.dispose();
|
||||||
|
source = dest;
|
||||||
|
}
|
||||||
|
int sizeX = Math.min(source.width, pix.width), sizeY = Math.min(source.height, pix.height);
|
||||||
|
for(int x = 0; x < sizeX; x++){
|
||||||
|
for(int y = 0; y < sizeY; y++){
|
||||||
|
int c = source.getRaw(x, y);
|
||||||
|
pix.setRaw(x, y, findClosest(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.draw(pix);
|
||||||
|
modified = true;
|
||||||
|
}catch(Exception e){
|
||||||
|
ui.showException("@editor.errorload", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int findClosest(int color){
|
||||||
|
//blend the new color over the bg color for more accurate selection
|
||||||
|
if(Color.ai(color) < 255){
|
||||||
|
color = Pixmap.blend(block.palette[0], color);
|
||||||
|
}
|
||||||
|
Tmp.c1.set(color);
|
||||||
|
float nearestDst = 100f;
|
||||||
|
int nearest = 0;
|
||||||
|
for(int i = 0; i < block.palette.length; i++){
|
||||||
|
if(block.palette[i] == color) return color;
|
||||||
|
Tmp.c2.set(block.palette[i]);
|
||||||
|
float dst = Tmp.c1.dst(Tmp.c2);
|
||||||
|
if(dst < nearestDst){
|
||||||
|
nearest = i;
|
||||||
|
nearestDst = dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return block.palette[nearest];
|
||||||
|
}
|
||||||
|
|
||||||
void save(){
|
void save(){
|
||||||
if(modified){
|
if(modified){
|
||||||
canvas.configure(canvas.packPixmap(pix));
|
canvas.configure(canvas.packPixmap(pix));
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ public class CanvasBlock extends Block{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPaletteFromString(String value){
|
||||||
|
String[] split = value.split("\n");
|
||||||
|
palette = new int[split.length];
|
||||||
|
for(int i = 0; i < split.length; i++){
|
||||||
|
palette[i] = (Integer.parseInt(split[i], 16) << 8) | 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
super.init();
|
super.init();
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ org.gradle.caching=true
|
|||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
android.enableR8.fullMode=false
|
android.enableR8.fullMode=false
|
||||||
archash=1abdd6e4bf
|
archash=900296c6e8
|
||||||
|
|||||||
Reference in New Issue
Block a user