Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -3,6 +3,7 @@ package mindustry.game;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.Texture.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
@@ -98,7 +99,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerLegacyMarker(String name, Prov<? extends ObjectiveMarker> prov) {
|
public static void registerLegacyMarker(String name, Prov<? extends ObjectiveMarker> prov){
|
||||||
Class<?> type = prov.get().getClass();
|
Class<?> type = prov.get().getClass();
|
||||||
|
|
||||||
markerNameToType.put(name, prov);
|
markerNameToType.put(name, prov);
|
||||||
@@ -663,7 +664,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Marker used for drawing various content to indicate something along with an objective. Mostly used as UI overlay. */
|
/** Marker used for drawing various content to indicate something along with an objective. Mostly used as UI overlay. */
|
||||||
public static abstract class ObjectiveMarker{
|
public static abstract class ObjectiveMarker{
|
||||||
/** Internal use only! Do not access. */
|
/** Internal use only! Do not access. */
|
||||||
public transient int arrayIndex;
|
public transient int arrayIndex;
|
||||||
@@ -933,7 +934,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
Lines.poly(pos.x, pos.y, sides, (radius + 1f) * scaleFactor, rotation + startAngle, rotation + endAngle);
|
Lines.poly(pos.x, pos.y, sides, (radius + 1f) * scaleFactor, rotation + startAngle, rotation + endAngle);
|
||||||
}else{
|
}else{
|
||||||
Draw.color(color);
|
Draw.color(color);
|
||||||
if (startAngle < endAngle){
|
if(startAngle < endAngle){
|
||||||
Fill.arc(pos.x, pos.y, radius * scaleFactor, (endAngle - startAngle) / 360f, rotation + startAngle, sides);
|
Fill.arc(pos.x, pos.y, radius * scaleFactor, (endAngle - startAngle) / 360f, rotation + startAngle, sides);
|
||||||
}else{
|
}else{
|
||||||
Fill.arc(pos.x, pos.y, radius * scaleFactor, (startAngle - endAngle) / 360f, rotation + endAngle, sides);
|
Fill.arc(pos.x, pos.y, radius * scaleFactor, (startAngle - endAngle) / 360f, rotation + endAngle, sides);
|
||||||
@@ -1091,7 +1092,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!Double.isNaN(p1) && !Double.isNaN(p2)){
|
if(!Double.isNaN(p1) && !Double.isNaN(p2)){
|
||||||
switch (type){
|
switch(type){
|
||||||
case posi -> ((int)p1 == 0 ? pos : (int)p1 == 1 ? endPos : Tmp.v1).x = (float)p2 * tilesize;
|
case posi -> ((int)p1 == 0 ? pos : (int)p1 == 1 ? endPos : Tmp.v1).x = (float)p2 * tilesize;
|
||||||
case colori -> ((int)p1 == 0 ? color1 : (int)p1 == 1 ? color2 : Tmp.c1).fromDouble(p2);
|
case colori -> ((int)p1 == 0 ? color1 : (int)p1 == 1 ? color2 : Tmp.c1).fromDouble(p2);
|
||||||
}
|
}
|
||||||
@@ -1179,7 +1180,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
private transient TextureRegion fetchedRegion;
|
private transient TextureRegion fetchedRegion;
|
||||||
|
|
||||||
public QuadMarker() {
|
public QuadMarker(){
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
vertices[i * 6 + 2] = Color.white.toFloatBits();
|
vertices[i * 6 + 2] = Color.white.toFloatBits();
|
||||||
vertices[i * 6 + 5] = Color.clearFloatBits;
|
vertices[i * 6 + 5] = Color.clearFloatBits;
|
||||||
@@ -1230,7 +1231,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
boolean firstUpdate = fetchedRegion == null;
|
boolean firstUpdate = fetchedRegion == null;
|
||||||
|
|
||||||
if(fetchedRegion == null) fetchedRegion = new TextureRegion();
|
if(firstUpdate) fetchedRegion = new TextureRegion();
|
||||||
Tmp.tr1.set(fetchedRegion);
|
Tmp.tr1.set(fetchedRegion);
|
||||||
|
|
||||||
lookupRegion(textureName, fetchedRegion);
|
lookupRegion(textureName, fetchedRegion);
|
||||||
@@ -1238,21 +1239,22 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
if(firstUpdate){
|
if(firstUpdate){
|
||||||
if(mapRegion){
|
if(mapRegion){
|
||||||
mapRegion = false;
|
mapRegion = false;
|
||||||
|
|
||||||
// possibly from the editor, we need to clamp the values
|
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
vertices[i * 6 + 3] = Mathf.map(Mathf.clamp(vertices[i * 6 + 3]), fetchedRegion.u, fetchedRegion.u2);
|
setUv(i, vertices[i * 6 + 3], vertices[i * 6 + 4]);
|
||||||
vertices[i * 6 + 4] = Mathf.map(1 - Mathf.clamp(vertices[i * 6 + 4]), fetchedRegion.v, fetchedRegion.v2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
vertices[i * 6 + 3] = Mathf.map(vertices[i * 6 + 3], Tmp.tr1.u, Tmp.tr1.u2, fetchedRegion.u, fetchedRegion.u2);
|
setUv(i, unmap(vertices[i * 6 + 3], Tmp.tr1.u, Tmp.tr1.u2), 1 - unmap(vertices[i * 6 + 4], Tmp.tr1.v, Tmp.tr1.v2));
|
||||||
vertices[i * 6 + 4] = Mathf.map(vertices[i * 6 + 4], Tmp.tr1.v, Tmp.tr1.v2, fetchedRegion.v, fetchedRegion.v2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float unmap(float x, float from, float to){
|
||||||
|
if(Mathf.equal(from, to)) return x;
|
||||||
|
return (x - from) / (to - from);
|
||||||
|
}
|
||||||
|
|
||||||
private void setPos(int i, double x, double y){
|
private void setPos(int i, double x, double y){
|
||||||
if(i >= 0 && i < 4){
|
if(i >= 0 && i < 4){
|
||||||
if(!Double.isNaN(x)) vertices[i * 6] = (float)x * tilesize;
|
if(!Double.isNaN(x)) vertices[i * 6] = (float)x * tilesize;
|
||||||
@@ -1270,11 +1272,16 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
if(i >= 0 && i < 4){
|
if(i >= 0 && i < 4){
|
||||||
if(fetchedRegion == null) setTexture(textureName);
|
if(fetchedRegion == null) setTexture(textureName);
|
||||||
|
|
||||||
if(!Double.isNaN(u)) vertices[i * 6 + 3] = Mathf.map(Mathf.clamp((float)u), fetchedRegion.u, fetchedRegion.u2);
|
if(!Double.isNaN(u)){
|
||||||
if(!Double.isNaN(v)) vertices[i * 6 + 4] = Mathf.map(1 - Mathf.clamp((float)v), fetchedRegion.v, fetchedRegion.v2);
|
boolean clampU = fetchedRegion.texture.getUWrap() != TextureWrap.mirroredRepeat && fetchedRegion.texture.getUWrap() != TextureWrap.repeat;
|
||||||
|
vertices[i * 6 + 3] = Mathf.map(clampU ? Mathf.clamp((float)u) : (float)u, fetchedRegion.u, fetchedRegion.u2);
|
||||||
|
}
|
||||||
|
if(!Double.isNaN(v)){
|
||||||
|
boolean clampV = fetchedRegion.texture.getVWrap() != TextureWrap.mirroredRepeat && fetchedRegion.texture.getVWrap() != TextureWrap.repeat;
|
||||||
|
vertices[i * 6 + 4] = Mathf.map(clampV ? 1 - Mathf.clamp((float)v) : 1 - (float)v, fetchedRegion.v, fetchedRegion.v2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void lookupRegion(String name, TextureRegion out){
|
private static void lookupRegion(String name, TextureRegion out){
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import mindustry.ui.*;
|
|||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
import mindustry.world.blocks.logic.*;
|
import mindustry.world.blocks.logic.*;
|
||||||
|
import mindustry.world.blocks.logic.CanvasBlock.*;
|
||||||
import mindustry.world.blocks.logic.LogicBlock.*;
|
import mindustry.world.blocks.logic.LogicBlock.*;
|
||||||
import mindustry.world.blocks.logic.LogicDisplay.*;
|
import mindustry.world.blocks.logic.LogicDisplay.*;
|
||||||
import mindustry.world.blocks.logic.MemoryBlock.*;
|
import mindustry.world.blocks.logic.MemoryBlock.*;
|
||||||
@@ -581,6 +582,8 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
}else if(target.isobj && target.objval instanceof CharSequence str){
|
}else if(target.isobj && target.objval instanceof CharSequence str){
|
||||||
output.setnum(address < 0 || address >= str.length() ? Double.NaN : (int)str.charAt(address));
|
output.setnum(address < 0 || address >= str.length() ? Double.NaN : (int)str.charAt(address));
|
||||||
|
}else if(from instanceof CanvasBuild canvas && (exec.privileged || (from.team == exec.team))){
|
||||||
|
output.setnum(canvas.getPixel(address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,6 +614,8 @@ public class LExecutor{
|
|||||||
toVar.numval = value.numval;
|
toVar.numval = value.numval;
|
||||||
toVar.isobj = value.isobj;
|
toVar.isobj = value.isobj;
|
||||||
}
|
}
|
||||||
|
}else if(from instanceof CanvasBuild canvas && (exec.privileged || (from.team == exec.team))){
|
||||||
|
canvas.setPixel(address, (int)(value.numval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import mindustry.annotations.Annotations.*;
|
|||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
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.*;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ public class CanvasBlock extends Block{
|
|||||||
public @Load("@-corner1") TextureRegion corner1;
|
public @Load("@-corner1") TextureRegion corner1;
|
||||||
public @Load("@-corner2") TextureRegion corner2;
|
public @Load("@-corner2") TextureRegion corner2;
|
||||||
|
|
||||||
protected @Nullable Pixmap previewPixmap;
|
protected @Nullable Pixmap previewPixmap; // please use only for previews
|
||||||
protected @Nullable Texture previewTexture;
|
protected @Nullable Texture previewTexture;
|
||||||
protected int tempBlend = 0;
|
protected int tempBlend = 0;
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ public class CanvasBlock extends Block{
|
|||||||
|
|
||||||
config(byte[].class, (CanvasBuild build, byte[] bytes) -> {
|
config(byte[].class, (CanvasBuild build, byte[] bytes) -> {
|
||||||
if(build.data.length == bytes.length){
|
if(build.data.length == bytes.length){
|
||||||
build.data = bytes;
|
System.arraycopy(bytes, 0, build.data, 0, bytes.length);
|
||||||
build.updateTexture();
|
build.updateTexture();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -65,13 +66,15 @@ public class CanvasBlock extends Block{
|
|||||||
bitsPerPixel = Mathf.log2(Mathf.nextPowerOfTwo(palette.length));
|
bitsPerPixel = Mathf.log2(Mathf.nextPowerOfTwo(palette.length));
|
||||||
|
|
||||||
clipSize = Math.max(clipSize, size * 8 - padding);
|
clipSize = Math.max(clipSize, size * 8 - padding);
|
||||||
|
|
||||||
|
previewPixmap = new Pixmap(canvasSize, canvasSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawPlanRegion(BuildPlan plan, Eachable<BuildPlan> list){
|
public void drawPlanRegion(BuildPlan plan, Eachable<BuildPlan> list){
|
||||||
//only draw the preview in schematics, as it lags otherwise
|
//only draw the preview in schematics, as it lags otherwise
|
||||||
if(!plan.worldContext && plan.config instanceof byte[] data){
|
if(!plan.worldContext && plan.config instanceof byte[] data){
|
||||||
Pixmap pix = makePixmap(data);
|
Pixmap pix = makePixmap(data, previewPixmap);
|
||||||
|
|
||||||
if(previewTexture == null){
|
if(previewTexture == null){
|
||||||
previewTexture = new Texture(pix);
|
previewTexture = new Texture(pix);
|
||||||
@@ -123,20 +126,15 @@ public class CanvasBlock extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns the same pixmap instance each time, use with care */
|
public Pixmap makePixmap(byte[] data, Pixmap target){
|
||||||
public Pixmap makePixmap(byte[] data){
|
|
||||||
if(previewPixmap == null){
|
|
||||||
previewPixmap = new Pixmap(canvasSize, canvasSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bpp = bitsPerPixel;
|
int bpp = bitsPerPixel;
|
||||||
int pixels = canvasSize * canvasSize;
|
int pixels = canvasSize * canvasSize;
|
||||||
for(int i = 0; i < pixels; i++){
|
for(int i = 0; i < pixels; i++){
|
||||||
int bitOffset = i * bpp;
|
int bitOffset = i * bpp;
|
||||||
int pal = getByte(data, bitOffset);
|
int pal = getByte(data, bitOffset);
|
||||||
previewPixmap.set(i % canvasSize, i / canvasSize, palette[pal]);
|
target.set(i % canvasSize, i / canvasSize, palette[pal]);
|
||||||
}
|
}
|
||||||
return previewPixmap;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getByte(byte[] data, int bitOffset){
|
protected int getByte(byte[] data, int bitOffset){
|
||||||
@@ -152,11 +150,41 @@ public class CanvasBlock extends Block{
|
|||||||
public @Nullable Texture texture;
|
public @Nullable Texture texture;
|
||||||
public byte[] data = new byte[Mathf.ceil(canvasSize * canvasSize * bitsPerPixel / 8f)];
|
public byte[] data = new byte[Mathf.ceil(canvasSize * canvasSize * bitsPerPixel / 8f)];
|
||||||
public int blending;
|
public int blending;
|
||||||
|
|
||||||
|
protected boolean updated = false;
|
||||||
|
|
||||||
|
public void setPixel(int pos, int index){
|
||||||
|
if(pos < canvasSize * canvasSize && pos >= 0 && index >= 0 && index < palette.length){
|
||||||
|
setByte(data, pos * bitsPerPixel, index);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPixel(int x, int y, int index){
|
||||||
|
if(x >= 0 && y >= 0 && x < canvasSize && y < canvasSize && index >= 0 && index < palette.length){
|
||||||
|
setByte(data, (y * canvasSize + x) * bitsPerPixel, index);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPixel(int pos){
|
||||||
|
if(pos >= 0 && pos < canvasSize * canvasSize){
|
||||||
|
return getByte(data, pos * bitsPerPixel);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPixel(int x, int y){
|
||||||
|
if(x >= 0 && y >= 0 && x < canvasSize && y < canvasSize){
|
||||||
|
return getByte(data, (y * canvasSize + x) * bitsPerPixel);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateTexture(){
|
public void updateTexture(){
|
||||||
if(headless) return;
|
if(headless) return;
|
||||||
|
|
||||||
Pixmap pix = makePixmap(data);
|
Pixmap pix = makePixmap(data, previewPixmap);
|
||||||
if(texture != null){
|
if(texture != null){
|
||||||
texture.draw(pix);
|
texture.draw(pix);
|
||||||
}else{
|
}else{
|
||||||
@@ -214,7 +242,8 @@ public class CanvasBlock extends Block{
|
|||||||
super.draw();
|
super.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(texture == null){
|
if(texture == null || updated){
|
||||||
|
updated = false;
|
||||||
updateTexture();
|
updateTexture();
|
||||||
}
|
}
|
||||||
Tmp.tr1.set(texture);
|
Tmp.tr1.set(texture);
|
||||||
@@ -237,6 +266,14 @@ public class CanvasBlock extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double sense(LAccess sensor){
|
||||||
|
return switch(sensor){
|
||||||
|
case displayWidth, displayHeight -> canvasSize;
|
||||||
|
default -> super.sense(sensor);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
@@ -252,12 +289,17 @@ public class CanvasBlock extends Block{
|
|||||||
table.button(Icon.pencil, Styles.cleari, () -> {
|
table.button(Icon.pencil, Styles.cleari, () -> {
|
||||||
Dialog dialog = new Dialog();
|
Dialog dialog = new Dialog();
|
||||||
|
|
||||||
Pixmap pix = makePixmap(data);
|
Pixmap pix = makePixmap(data, new Pixmap(canvasSize, canvasSize));
|
||||||
Texture texture = new Texture(pix);
|
Texture texture = new Texture(pix);
|
||||||
int[] curColor = {palette[0]};
|
int[] curColor = {palette[0]};
|
||||||
boolean[] modified = {false};
|
boolean[] modified = {false};
|
||||||
boolean[] fill = {false};
|
boolean[] fill = {false};
|
||||||
|
|
||||||
|
dialog.hidden(() -> {
|
||||||
|
texture.dispose();
|
||||||
|
pix.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
dialog.resized(dialog::hide);
|
dialog.resized(dialog::hide);
|
||||||
|
|
||||||
dialog.cont.table(Tex.pane, body -> {
|
dialog.cont.table(Tex.pane, body -> {
|
||||||
@@ -395,7 +437,6 @@ public class CanvasBlock extends Block{
|
|||||||
dialog.buttons.button("@ok", Icon.ok, () -> {
|
dialog.buttons.button("@ok", Icon.ok, () -> {
|
||||||
if(modified[0]){
|
if(modified[0]){
|
||||||
configure(packPixmap(pix));
|
configure(packPixmap(pix));
|
||||||
texture.dispose();
|
|
||||||
}
|
}
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user