mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-12-06 02:40:23 -08:00
Better colored floor/wall support
This commit is contained in:
parent
4c8f956fef
commit
24cfb000de
19 changed files with 134 additions and 84 deletions
BIN
core/assets-raw/sprites/blocks/environment/colored-floor.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/colored-floor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 B |
BIN
core/assets-raw/sprites/blocks/environment/colored-wall.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/colored-wall.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 266 B |
|
|
@ -121,6 +121,7 @@ continue = Continue
|
|||
maps.none = [lightgray]No maps found!
|
||||
invalid = Invalid
|
||||
pickcolor = Pick Color
|
||||
color = Color
|
||||
preparingconfig = Preparing Config
|
||||
preparingcontent = Preparing Content
|
||||
uploadingcontent = Uploading Content
|
||||
|
|
|
|||
|
|
@ -905,16 +905,10 @@ public class Blocks{
|
|||
autotile = true;
|
||||
drawEdgeOut = false;
|
||||
drawEdgeIn = false;
|
||||
//there is no proper support for displaying colors or placing with colors
|
||||
inEditor = false;
|
||||
}};
|
||||
|
||||
coloredWall = new ColoredWall("colored-wall"){{
|
||||
autotile = true;
|
||||
//there is no proper support for displaying colors or placing with colors
|
||||
inEditor = false;
|
||||
//TODO: should this apply darkness?
|
||||
//fillsTile = false;
|
||||
}};
|
||||
|
||||
Seq.with(metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor4, metalFloor5, darkPanel1, darkPanel2, darkPanel3, darkPanel4, darkPanel5, darkPanel6)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public class EditorTile extends Tile{
|
|||
op(DrawOperation.opFloor, floor.id);
|
||||
|
||||
this.floor = type;
|
||||
type.floorChanged(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ public class MapRenderer implements Disposable{
|
|||
width, height,
|
||||
tile.build == null || !wall.rotate ? 0 : tile.build.rotdeg());
|
||||
}else{
|
||||
if(floor instanceof ColoredFloor){
|
||||
mesh.setColor(Tmp.c1.set(tile.extraData | 0xff));
|
||||
}
|
||||
|
||||
region = floor.editorVariantRegions()[Mathf.randomSeed(idxWall, 0, floor.editorVariantRegions().length - 1)];
|
||||
|
||||
mesh.draw(idxWall, region, wx * tilesize, wy * tilesize, 8, 8);
|
||||
|
|
@ -155,6 +159,8 @@ public class MapRenderer implements Disposable{
|
|||
if(wall == Blocks.cliff){
|
||||
mesh.setColor(Tmp.c1.set(floor.mapColor).mul(1.6f));
|
||||
region = ((Cliff)Blocks.cliff).editorCliffs[tile.data & 0xff];
|
||||
}else if(wall instanceof ColoredWall){
|
||||
mesh.setColor(Tmp.c1.set(tile.extraData | 0xff));
|
||||
}
|
||||
|
||||
offsetX = tilesize / 2f - region.width * region.scl() / 2f;
|
||||
|
|
|
|||
|
|
@ -1627,6 +1627,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||
/** Draws a placement icon for a specific block. */
|
||||
protected void drawPlan(int x, int y, Block block, int rotation){
|
||||
bplan.set(x, y, rotation, block);
|
||||
if(block.saveConfig){
|
||||
bplan.config = block.lastConfig;
|
||||
}
|
||||
bplan.animScale = 1f;
|
||||
block.drawPlan(bplan, allPlans(), validPlace(x, y, block, rotation));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,23 @@ public class MapIO{
|
|||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReadTileData(){
|
||||
//colored floor/wall tile data will affect the map preview
|
||||
|
||||
if(!tile.block().synthetic() && tile.block() != Blocks.air){
|
||||
int color = tile.block().minimapColor(tile);
|
||||
if(color != 0){
|
||||
walls.set(tile.x, walls.height - 1 - tile.y, color);
|
||||
}
|
||||
}else if(tile.overlay() == Blocks.air && tile.block() == Blocks.air){
|
||||
int color = tile.floor().minimapColor(tile);
|
||||
if(color != 0){
|
||||
floors.set(tile.x, floors.height - 1 - tile.y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
floors.draw(walls, true);
|
||||
|
|
@ -154,7 +171,14 @@ public class MapIO{
|
|||
for(int x = 0; x < pixmap.width; x++){
|
||||
for(int y = 0; y < pixmap.height; y++){
|
||||
Tile tile = tiles.getn(x, y);
|
||||
pixmap.set(x, pixmap.height - 1 - y, colorFor(tile.block(), tile.floor(), tile.overlay(), tile.team()));
|
||||
int color = 0;
|
||||
if(!tile.block().synthetic() && tile.block() != Blocks.air){
|
||||
color = tile.block().minimapColor(tile);
|
||||
}else if(tile.overlay() == Blocks.air && tile.block() == Blocks.air){
|
||||
color = tile.floor().minimapColor(tile);
|
||||
}
|
||||
if(color == 0) color = colorFor(tile.block(), tile.floor(), tile.overlay(), tile.team());
|
||||
pixmap.set(x, pixmap.height - 1 - y, color);
|
||||
}
|
||||
}
|
||||
return pixmap;
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||
tile.floorData = floorData;
|
||||
tile.overlayData = overlayData;
|
||||
tile.extraData = extraData;
|
||||
context.onReadTileData();
|
||||
}
|
||||
|
||||
if(hadEntity){
|
||||
|
|
|
|||
|
|
@ -78,6 +78,24 @@ public class HudFragment{
|
|||
.name("editor/search").maxTextLength(maxNameLength).get().setMessageText("@players.search");
|
||||
}).growX().pad(-2).padLeft(6f);
|
||||
cont.row();
|
||||
cont.collapser(t -> {
|
||||
t.button(b -> {
|
||||
b.margin(4f);
|
||||
b.left();
|
||||
b.table(Tex.pane, in -> {
|
||||
in.image(Tex.whiteui).update(i -> {
|
||||
if(control.input.block != null && control.input.block.lastConfig instanceof Integer col){
|
||||
i.color.set(col | 0xff);
|
||||
}
|
||||
}).grow();
|
||||
}).margin(4).size(50f).padRight(10);
|
||||
b.add("@color");
|
||||
}, Styles.cleart, () -> ui.picker.show(control.input.block != null && control.input.block.lastConfig instanceof Integer col ? new Color(col | 0xff) : new Color(Color.white), false, col -> {
|
||||
if(control.input.block != null){
|
||||
control.input.block.lastConfig = col.rgba8888();
|
||||
}
|
||||
})).left().width(250f).pad(3f).row();
|
||||
}, () -> control.input.block != null && control.input.block.showColorEdit).growX().row();
|
||||
cont.add(pane).expandY().top().left();
|
||||
|
||||
rebuildBlockSelection(blockSelection, "");
|
||||
|
|
|
|||
|
|
@ -126,39 +126,41 @@ public class PlacementFragment{
|
|||
}
|
||||
|
||||
boolean updatePick(InputHandler input){
|
||||
if(Core.input.keyTap(Binding.pick) && player.isBuilder() && !Core.scene.hasDialog()){ //mouse eyedropper select
|
||||
var build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
Tile tile = world.tileWorld(Core.input.mouseWorldX(), Core.input.mouseWorldY());
|
||||
if(tile != null && Core.input.keyTap(Binding.pick) && player.isBuilder() && !Core.scene.hasDialog()){ //mouse eyedropper select
|
||||
var build = tile.build;
|
||||
|
||||
//can't middle click buildings in fog
|
||||
if(build != null && build.inFogTo(player.team())){
|
||||
build = null;
|
||||
}
|
||||
|
||||
Block tryRecipe = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block;
|
||||
Block tryBlock = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block;
|
||||
Object tryConfig = build == null || !build.block.copyConfig ? null : build.config();
|
||||
|
||||
if(tryBlock != null && tryBlock.showColorEdit && tryConfig == null){
|
||||
tryConfig = tile.extraData;
|
||||
}
|
||||
|
||||
for(BuildPlan req : player.unit().plans()){
|
||||
if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){
|
||||
tryRecipe = req.block;
|
||||
tryBlock = req.block;
|
||||
tryConfig = req.config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(tryRecipe == null && state.rules.editor){
|
||||
var tile = world.tileWorld(Core.input.mouseWorldX(), Core.input.mouseWorldY());
|
||||
if(tile != null){
|
||||
tryRecipe =
|
||||
if(tryBlock == null && state.rules.editor){
|
||||
tryBlock =
|
||||
tile.block() != Blocks.air ? tile.block() :
|
||||
tile.overlay() != Blocks.air ? tile.overlay() :
|
||||
tile.floor() != Blocks.air ? tile.floor() : null;
|
||||
}
|
||||
}
|
||||
|
||||
if(tryRecipe != null && ((tryRecipe.isVisible() && unlocked(tryRecipe)) || state.rules.editor)){
|
||||
input.block = tryRecipe;
|
||||
tryRecipe.lastConfig = tryConfig;
|
||||
if(tryRecipe.isVisible()){
|
||||
if(tryBlock != null && ((tryBlock.isVisible() && unlocked(tryBlock)) || state.rules.editor)){
|
||||
input.block = tryBlock;
|
||||
tryBlock.lastConfig = tryConfig;
|
||||
if(tryBlock.isVisible()){
|
||||
currentCategory = input.block.category;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ public class Block extends UnlockableContent implements Senseable{
|
|||
public boolean displayFlow = true;
|
||||
/** whether this block is visible in the editor */
|
||||
public boolean inEditor = true;
|
||||
/** if true, a color picker will be shown for the lastConfig field in the in-game-editor, and will be assigned as an integer. */
|
||||
public boolean showColorEdit;
|
||||
/** the last configuration value applied to this block. */
|
||||
public @Nullable Object lastConfig;
|
||||
/** whether to save the last config and apply it to newly placed blocks */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ public interface WorldContext{
|
|||
/** Called when a building is finished reading. */
|
||||
default void onReadBuilding(){}
|
||||
|
||||
/** Called when data finishes reading for a tile. */
|
||||
default void onReadTileData(){}
|
||||
|
||||
default @Nullable Sector getSector(){
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@ public class ColoredFloor extends Floor{
|
|||
public ColoredFloor(String name){
|
||||
super(name);
|
||||
saveData = true;
|
||||
showColorEdit = true;
|
||||
saveConfig = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
defaultColorRgba = defaultColor.rgba();
|
||||
lastConfig = defaultColorRgba = defaultColor.rgba();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -132,7 +134,9 @@ public class ColoredFloor extends Floor{
|
|||
@Override
|
||||
public void floorChanged(Tile tile){
|
||||
//reset to white
|
||||
tile.extraData = defaultColorRgba;
|
||||
if(tile.extraData == 0){
|
||||
tile.extraData = defaultColorRgba;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -19,17 +19,19 @@ public class ColoredWall extends StaticWall{
|
|||
public ColoredWall(String name){
|
||||
super(name);
|
||||
saveData = true;
|
||||
showColorEdit = true;
|
||||
saveConfig = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
super.init();
|
||||
defaultColorRgba = defaultColor.rgba();
|
||||
lastConfig = defaultColorRgba = defaultColor.rgba();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBase(Tile tile){
|
||||
//make sure to mask out the alpha channel - it's generally undesirable, and leads to invisible blocks when the data is not initialized
|
||||
//make sure to mask out the alpha channel - it's generally undesirable, and leads to invisible blocks when thtoe data is not initialized
|
||||
Draw.color(tile.extraData | 0xff);
|
||||
super.drawBase(tile);
|
||||
Draw.color();
|
||||
|
|
@ -37,8 +39,10 @@ public class ColoredWall extends StaticWall{
|
|||
|
||||
@Override
|
||||
public void blockChanged(Tile tile){
|
||||
//reset to white
|
||||
tile.extraData = defaultColorRgba;
|
||||
//reset to white on first placement
|
||||
if(tile.extraData == 0){
|
||||
tile.extraData = defaultColorRgba;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -59,12 +63,12 @@ public class ColoredWall extends StaticWall{
|
|||
|
||||
@Override
|
||||
public boolean checkAutotileSame(Tile tile, @Nullable Tile other){
|
||||
return other != null && other.block() == this && ((tile.extraData & flagIgnoreDifferentColor) != 0 || tile.extraData == other.extraData);
|
||||
return other != null && other.block() == this && ((tile.extraData == flagIgnoreDifferentColor) || tile.extraData == other.extraData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDarkened(Tile tile){
|
||||
return (tile.extraData & flagApplyDarkness) != 0;
|
||||
return (tile.extraData == flagApplyDarkness);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -378,19 +378,6 @@ public class Floor extends Block{
|
|||
}
|
||||
}
|
||||
|
||||
//'new' style of edges with shadows instead of colors, not used currently
|
||||
protected void drawEdgesFlat(Tile tile, boolean sameLayer){
|
||||
for(int i = 0; i < 4; i++){
|
||||
Tile other = tile.nearby(i);
|
||||
if(other != null && doEdge(tile, other, other.floor())){
|
||||
Color color = other.floor().mapColor;
|
||||
Draw.color(color.r, color.g, color.b, 1f);
|
||||
Draw.rect(edgeRegion, tile.worldx(), tile.worldy(), i*90);
|
||||
}
|
||||
}
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
public int realBlendId(Tile tile){
|
||||
if(tile.floor().isLiquid && !tile.overlay().isAir() && !(tile.overlay() instanceof OreBlock)){
|
||||
return -((tile.overlay().blendId) | (tile.floor().blendId << 15));
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import static mindustry.Vars.*;
|
|||
public class DesktopLauncher extends ClientLauncher{
|
||||
public final static long discordID = 610508934456934412L;
|
||||
public final String[] args;
|
||||
|
||||
|
||||
boolean useDiscord = !OS.hasProp("nodiscord"), loadError = false;
|
||||
Throwable steamError;
|
||||
|
||||
|
|
@ -48,21 +48,17 @@ public class DesktopLauncher extends ClientLauncher{
|
|||
for(int i = 0; i < arg.length; i++){
|
||||
if(arg[i].charAt(0) == '-'){
|
||||
String name = arg[i].substring(1);
|
||||
try{
|
||||
switch(name){
|
||||
case "width": width = Strings.parseInt(arg[i + 1], width); break;
|
||||
case "height": height = Strings.parseInt(arg[i + 1], height); break;
|
||||
case "glMajor": gl30Major = Strings.parseInt(arg[i + 1], gl30Major);
|
||||
case "glMinor": gl30Minor = Strings.parseInt(arg[i + 1], gl30Minor);
|
||||
case "gl3": gl30 = true; break;
|
||||
case "gl2": gl30 = false; break;
|
||||
case "coreGl": coreProfile = true; break;
|
||||
case "antialias": samples = 16; break;
|
||||
case "debug": Log.level = LogLevel.debug; break;
|
||||
case "maximized": maximized = Boolean.parseBoolean(arg[i + 1]); break;
|
||||
}
|
||||
}catch(NumberFormatException number){
|
||||
Log.warn("Invalid parameter number value.");
|
||||
switch(name){
|
||||
case "width": width = Strings.parseInt(arg[i + 1], width); break;
|
||||
case "height": height = Strings.parseInt(arg[i + 1], height); break;
|
||||
case "glMajor": gl30Major = Strings.parseInt(arg[i + 1], gl30Major);
|
||||
case "glMinor": gl30Minor = Strings.parseInt(arg[i + 1], gl30Minor);
|
||||
case "gl3": gl30 = true; break;
|
||||
case "gl2": gl30 = false; break;
|
||||
case "coreGl": coreProfile = true; break;
|
||||
case "antialias": samples = 16; break;
|
||||
case "debug": Log.level = LogLevel.debug; break;
|
||||
case "maximized": maximized = Boolean.parseBoolean(arg[i + 1]); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,7 +71,7 @@ public class DesktopLauncher extends ClientLauncher{
|
|||
|
||||
public DesktopLauncher(String[] args){
|
||||
this.args = args;
|
||||
|
||||
|
||||
Version.init();
|
||||
boolean useSteam = Version.modifier.contains("steam");
|
||||
testMobile = Seq.with(args).contains("-testMobile");
|
||||
|
|
|
|||
|
|
@ -26,4 +26,4 @@ org.gradle.caching=true
|
|||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
android.enableR8.fullMode=false
|
||||
archash=ae3b50eaca
|
||||
archash=f18ba925db
|
||||
|
|
|
|||
|
|
@ -394,34 +394,38 @@ public class Generators{
|
|||
save(padded, region.name);
|
||||
}
|
||||
|
||||
if(!regions[0].found()){
|
||||
Pixmap image;
|
||||
|
||||
if(regions[0].found()){
|
||||
image = get(regions[0]);
|
||||
|
||||
int i = 0;
|
||||
for(TextureRegion region : regions){
|
||||
i++;
|
||||
if(i != regions.length || last == null){
|
||||
image.draw(get(region), true);
|
||||
}else{
|
||||
image.draw(last, true);
|
||||
}
|
||||
|
||||
//draw shard (default team top) on top of first sprite
|
||||
if(region == block.teamRegions[Team.sharded.id] && shardTeamTop != null){
|
||||
image.draw(shardTeamTop, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(regions.length == 1 && regions[0] == Core.atlas.find(block.name) && shardTeamTop == null)){
|
||||
save(image, "block-" + block.name + "-full");
|
||||
}
|
||||
|
||||
save(image, "../editor/" + block.name + "-icon-editor");
|
||||
saveScaled(image, "../ui/block-" + block.name + "-ui", Math.min(image.width, maxUiIcon));
|
||||
}else if(gens.containsKey(block)){
|
||||
image = gens.get(block);
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
|
||||
Pixmap image = get(regions[0]);
|
||||
|
||||
int i = 0;
|
||||
for(TextureRegion region : regions){
|
||||
i++;
|
||||
if(i != regions.length || last == null){
|
||||
image.draw(get(region), true);
|
||||
}else{
|
||||
image.draw(last, true);
|
||||
}
|
||||
|
||||
//draw shard (default team top) on top of first sprite
|
||||
if(region == block.teamRegions[Team.sharded.id] && shardTeamTop != null){
|
||||
image.draw(shardTeamTop, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(regions.length == 1 && regions[0] == Core.atlas.find(block.name) && shardTeamTop == null)){
|
||||
save(image, "block-" + block.name + "-full");
|
||||
}
|
||||
|
||||
save(image, "../editor/" + block.name + "-icon-editor");
|
||||
saveScaled(image, "../ui/block-" + block.name + "-ui", Math.min(image.width, maxUiIcon));
|
||||
|
||||
boolean hasEmpty = false;
|
||||
Color average = new Color(), c = new Color();
|
||||
float asum = 0f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue