From 7cc000ed46a90c5ee9a5fa98bc250e02ed9e7a1c Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 13 Jul 2025 17:00:12 -0400 Subject: [PATCH] Made tiles not clear overlay on setFloor + cleanup/refactor --- core/src/mindustry/editor/DrawOperation.java | 75 ++++++++++--------- core/src/mindustry/editor/EditorTile.java | 30 ++++---- core/src/mindustry/editor/EditorTool.java | 2 +- core/src/mindustry/editor/MapEditor.java | 3 +- .../mindustry/entities/comp/BuilderComp.java | 2 +- core/src/mindustry/io/MapIO.java | 2 +- core/src/mindustry/world/Build.java | 6 +- core/src/mindustry/world/Tile.java | 19 +---- .../world/blocks/ConstructBlock.java | 4 +- .../blocks/environment/ColoredFloor.java | 17 +++++ .../world/blocks/environment/Floor.java | 3 + 11 files changed, 85 insertions(+), 78 deletions(-) diff --git a/core/src/mindustry/editor/DrawOperation.java b/core/src/mindustry/editor/DrawOperation.java index 6ef2d2e3b4..163546bfc3 100755 --- a/core/src/mindustry/editor/DrawOperation.java +++ b/core/src/mindustry/editor/DrawOperation.java @@ -10,6 +10,13 @@ import mindustry.world.blocks.environment.*; import static mindustry.Vars.*; public class DrawOperation{ + static final int + opFloor = 0, + opBlock = 1, + opRotation = 2, + opTeam = 3, + opOverlay = 4; + private LongSeq array = new LongSeq(); public boolean isEmpty(){ @@ -39,42 +46,44 @@ public class DrawOperation{ } short getTile(Tile tile, byte type){ - if(type == OpType.floor.ordinal()){ - return tile.floorID(); - }else if(type == OpType.block.ordinal()){ - return tile.blockID(); - }else if(type == OpType.rotation.ordinal()){ - return tile.build == null ? 0 : (byte)tile.build.rotation; - }else if(type == OpType.team.ordinal()){ - return (byte)tile.getTeamID(); - }else if(type == OpType.overlay.ordinal()){ - return tile.overlayID(); - } - throw new IllegalArgumentException("Invalid type."); + return switch(type){ + case opFloor -> tile.floorID(); + case opOverlay -> tile.overlayID(); + case opBlock -> tile.blockID(); + case opRotation -> tile.build == null ? 0 : (byte)tile.build.rotation; + case opTeam -> (byte)tile.getTeamID(); + default -> throw new IllegalArgumentException("Invalid type."); + }; } void setTile(Tile tile, byte type, short to){ editor.load(() -> { - if(type == OpType.floor.ordinal()){ - if(content.block(to) instanceof Floor floor){ - tile.setFloor(floor); + switch(type){ + case opFloor -> { + if(content.block(to) instanceof Floor floor){ + tile.setFloor(floor); + } } - }else if(type == OpType.block.ordinal()){ - tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y)); - - Block block = content.block(to); - tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation); - if(tile.build != null){ - tile.build.enabled = true; + case opOverlay -> { + if(content.block(to) instanceof Floor floor){ + tile.setOverlay(floor); + } } + case opBlock -> { + tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y)); - tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y)); - }else if(type == OpType.rotation.ordinal()){ - if(tile.build != null) tile.build.rotation = to; - }else if(type == OpType.team.ordinal()){ - tile.setTeam(Team.get(to)); - }else if(type == OpType.overlay.ordinal()){ - tile.setOverlayID(to); + Block block = content.block(to); + tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation); + if(tile.build != null){ + tile.build.enabled = true; + } + + tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y)); + } + case opRotation -> { + if(tile.build != null) tile.build.rotation = to; + } + case opTeam -> tile.setTeam(Team.get(to)); } }); editor.renderer.updatePoint(tile.x, tile.y); @@ -87,12 +96,4 @@ public class DrawOperation{ byte type; short value; } - - public enum OpType{ - floor, - block, - rotation, - team, - overlay - } } diff --git a/core/src/mindustry/editor/EditorTile.java b/core/src/mindustry/editor/EditorTile.java index b4ff3f1296..4a744772a6 100644 --- a/core/src/mindustry/editor/EditorTile.java +++ b/core/src/mindustry/editor/EditorTile.java @@ -2,7 +2,6 @@ package mindustry.editor; import arc.func.*; import mindustry.content.*; -import mindustry.editor.DrawOperation.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.world.*; @@ -27,17 +26,16 @@ public class EditorTile extends Tile{ if(type instanceof OverlayFloor){ //don't place on liquids if(floor.hasSurface() || !type.needsSurface){ - setOverlayID(type.id); + setOverlay(type); } return; } - if(floor == type && overlayID() == 0) return; - if(overlayID() != 0) op(OpType.overlay, overlayID()); - if(floor != type) op(OpType.floor, floor.id); + if(floor == type) return; + + op(DrawOperation.opFloor, floor.id); this.floor = type; - this.overlay = (Floor)Blocks.air; } @Override @@ -59,14 +57,14 @@ public class EditorTile extends Tile{ if(!isCenter()){ EditorTile cen = (EditorTile)build.tile; - cen.op(OpType.rotation, (byte)build.rotation); - cen.op(OpType.team, (byte)build.team.id); - cen.op(OpType.block, block.id); + cen.op(DrawOperation.opRotation, (byte)build.rotation); + cen.op(DrawOperation.opTeam, (byte)build.team.id); + cen.op(DrawOperation.opBlock, block.id); update(); }else{ - if(build != null) op(OpType.rotation, (byte)build.rotation); - if(build != null) op(OpType.team, (byte)build.team.id); - op(OpType.block, block.id); + if(build != null) op(DrawOperation.opRotation, (byte)build.rotation); + if(build != null) op(DrawOperation.opTeam, (byte)build.team.id); + op(DrawOperation.opBlock, block.id); } @@ -81,7 +79,7 @@ public class EditorTile extends Tile{ } if(getTeamID() == team.id) return; - op(OpType.team, (byte)getTeamID()); + op(DrawOperation.opTeam, (byte)getTeamID()); super.setTeam(team); getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y)); @@ -96,7 +94,7 @@ public class EditorTile extends Tile{ if(!floor.hasSurface() && overlay.asFloor().needsSurface && (overlay instanceof OreBlock || !floor.supportsOverlay)) return; if(overlay() == overlay) return; - op(OpType.overlay, this.overlay.id); + op(DrawOperation.opOverlay, this.overlay.id); super.setOverlay(overlay); } @@ -162,7 +160,7 @@ public class EditorTile extends Tile{ return state.isGame() || editor.isLoading() || world.isGenerating(); } - private void op(OpType type, short value){ - editor.addTileOp(TileOp.get(x, y, (byte)type.ordinal(), value)); + private void op(int type, short value){ + editor.addTileOp(TileOp.get(x, y, (byte)type, value)); } } diff --git a/core/src/mindustry/editor/EditorTool.java b/core/src/mindustry/editor/EditorTool.java index 50c7a2aca9..6848ae8f40 100644 --- a/core/src/mindustry/editor/EditorTool.java +++ b/core/src/mindustry/editor/EditorTool.java @@ -131,7 +131,7 @@ public enum EditorTool{ Block dest = tile.floor(); if(dest == editor.drawBlock) return; tester = t -> t.floor() == dest; - setter = t -> t.setFloorUnder(editor.drawBlock.asFloor()); + setter = t -> t.setFloor(editor.drawBlock.asFloor()); }else{ Block dest = tile.block(); if(dest == editor.drawBlock) return; diff --git a/core/src/mindustry/editor/MapEditor.java b/core/src/mindustry/editor/MapEditor.java index 38839e6108..7df7f67ea6 100644 --- a/core/src/mindustry/editor/MapEditor.java +++ b/core/src/mindustry/editor/MapEditor.java @@ -7,7 +7,6 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.*; import mindustry.content.*; -import mindustry.editor.DrawOperation.*; import mindustry.entities.units.*; import mindustry.game.*; import mindustry.gen.*; @@ -166,7 +165,7 @@ public class MapEditor{ } }else if(!(tile.block().isMultiblock() && !drawBlock.isMultiblock())){ if(drawBlock.rotate && tile.build != null && tile.build.rotation != rotation){ - addTileOp(TileOp.get(tile.x, tile.y, (byte)OpType.rotation.ordinal(), (byte)rotation)); + addTileOp(TileOp.get(tile.x, tile.y, (byte)DrawOperation.opRotation, (byte)rotation)); } tile.setBlock(drawBlock, drawTeam, rotation); diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index 65bacbbd2c..3ab723995c 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -145,7 +145,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{ !Structs.contains(current.block.requirements, i -> !core.items.has(i.item, Math.min(Mathf.round(i.amount * state.rules.buildCostMultiplier), 1))); if(hasAll){ - Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation); + Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation, current.block.instantBuild ? current.config : null); if(!net.client() && current.block.instantBuild){ if(plans.size > 0){ diff --git a/core/src/mindustry/io/MapIO.java b/core/src/mindustry/io/MapIO.java index 26cc9cd8ac..8676d62f5a 100644 --- a/core/src/mindustry/io/MapIO.java +++ b/core/src/mindustry/io/MapIO.java @@ -200,7 +200,7 @@ public class MapIO{ for(Tile tile : tiles){ //default to stone floor if(tile.floor() == Blocks.air){ - tile.setFloorUnder((Floor)Blocks.stone); + tile.setFloor((Floor)Blocks.stone); } } } diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index 8340229257..6948e6910e 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -66,9 +66,9 @@ public class Build{ Events.fire(new BlockBuildBeginEvent(tile, team, unit, true)); } - /** Places a ConstructBlock at this location. */ + /** Places a ConstructBlock at this location. To preserve bandwidth, a config is only passed in the case of instant-place blocks. */ @Remote(called = Loc.server) - public static void beginPlace(@Nullable Unit unit, Block result, Team team, int x, int y, int rotation){ + public static void beginPlace(@Nullable Unit unit, Block result, Team team, int x, int y, int rotation, @Nullable Object placeConfig){ if(!validPlace(result, team, x, y, rotation)){ return; } @@ -127,7 +127,7 @@ public class Build{ if(result.instantBuild){ Events.fire(new BlockBuildBeginEvent(tile, team, unit, false)); result.placeBegan(tile, tile.block, unit); - ConstructBlock.constructFinish(tile, result, unit, (byte)rotation, team, null); + ConstructBlock.constructFinish(tile, result, unit, (byte)rotation, team, placeConfig); return; } diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index fac7607edb..cab73a3586 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -290,11 +290,11 @@ public class Tile implements Position, QuadTreeObject, Displayable{ setBlock(type, Team.derelict, 0); } - /** This resets the overlay! */ public void setFloor(Floor type){ + if(this.floor == type) return; + var prev = this.floor; this.floor = type; - this.overlay = (Floor)Blocks.air; if(!headless && !world.isGenerating() && !isEditorTile()){ renderer.blocks.removeFloorIndex(this); @@ -321,15 +321,6 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return false; } - /** Sets the floor, preserving overlay.*/ - public void setFloorUnder(Floor floor){ - Block overlay = this.overlay; - setFloor(floor); - if(this.overlay != overlay){ - setOverlay(overlay); - } - } - /** Sets the block to air. */ public void setAir(){ setBlock(Blocks.air); @@ -412,10 +403,6 @@ public class Tile implements Position, QuadTreeObject, Displayable{ return floor.id; } - public void setOverlayID(short ore){ - setOverlay(content.block(ore)); - } - public void setOverlay(Block block){ this.overlay = (Floor)block; @@ -431,7 +418,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{ } public void clearOverlay(){ - setOverlayID((short)0); + setOverlay(Blocks.air); } public boolean passable(){ diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index 3e53462cf1..77f6288ab1 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -77,8 +77,10 @@ public class ConstructBlock extends Block{ if(block instanceof OverlayFloor overlay){ tile.setOverlay(overlay); + overlay.placed(tile, config); }else if(block instanceof Floor floor){ - tile.setFloorUnder(floor); + tile.setFloor(floor); + floor.placed(tile, config); }else{ tile.setBlock(block, team, rotation); } diff --git a/core/src/mindustry/world/blocks/environment/ColoredFloor.java b/core/src/mindustry/world/blocks/environment/ColoredFloor.java index 7e1985907a..2a6b2b6a2d 100644 --- a/core/src/mindustry/world/blocks/environment/ColoredFloor.java +++ b/core/src/mindustry/world/blocks/environment/ColoredFloor.java @@ -5,6 +5,7 @@ import arc.graphics.g2d.*; import arc.math.geom.*; import arc.util.*; import mindustry.*; +import mindustry.entities.units.*; import mindustry.world.*; import mindustry.world.blocks.*; @@ -133,6 +134,22 @@ public class ColoredFloor extends Floor{ tile.extraData = defaultColorRgba; } + @Override + public void placed(Tile tile, @Nullable Object config){ + //config is assumed to be an integer RGBA color + if(config instanceof Integer i){ + tile.extraData = i; + } + } + + @Override + public void drawPlanRegion(BuildPlan plan, Eachable list){ + if(plan.config instanceof Integer i){ + Draw.tint(Tmp.c1.set(i | 0xff)); + } + drawDefaultPlanRegion(plan, list); + } + @Override public boolean checkAutotileSame(Tile tile, @Nullable Tile other){ return other != null && other.floor().blendGroup == blendGroup && ((tile.extraData & 0xff) == flagIgnoreDifferentColor || tile.extraData == other.extraData); diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java index e334dc625c..e14a517f5b 100644 --- a/core/src/mindustry/world/blocks/environment/Floor.java +++ b/core/src/mindustry/world/blocks/environment/Floor.java @@ -275,6 +275,9 @@ public class Floor extends Block{ /** Called when this floor is set on the specified tile. */ public void floorChanged(Tile tile){} + /** Called when this floor or overlay is placed on a tile. The config may be null. */ + public void placed(Tile tile, @Nullable Object config){} + /** @return whether to index this floor by flag */ public boolean shouldIndex(Tile tile){ return true;