In-game editor UI improvements

This commit is contained in:
Anuken 2024-10-03 14:44:33 -04:00
parent 24daa1e933
commit 15ca672179
15 changed files with 230 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

View File

@ -1563,6 +1563,8 @@ block.graphite-press.name = Graphite Press
block.multi-press.name = Multi-Press block.multi-press.name = Multi-Press
block.constructing = {0} [lightgray](Constructing) block.constructing = {0} [lightgray](Constructing)
block.spawn.name = Enemy Spawn block.spawn.name = Enemy Spawn
block.remove-wall.name = Remove Wall
block.remove-ore.name = Remove Ore
block.core-shard.name = Core: Shard block.core-shard.name = Core: Shard
block.core-foundation.name = Core: Foundation block.core-foundation.name = Core: Foundation
block.core-nucleus.name = Core: Nucleus block.core-nucleus.name = Core: Nucleus

View File

@ -588,3 +588,5 @@
63094=cat|cat 63094=cat|cat
63093=world-switch|block-world-switch-ui 63093=world-switch|block-world-switch-ui
63092=dynamic|status-dynamic-ui 63092=dynamic|status-dynamic-ui
63091=remove-wall|block-remove-wall-ui
63090=remove-ore|block-remove-ore-ui

View File

@ -43,7 +43,7 @@ public class Blocks{
public static Block public static Block
//environment //environment
air, spawn, cliff, deepwater, water, taintedWater, deepTaintedWater, tar, slag, cryofluid, stone, craters, charr, sand, darksand, dirt, mud, ice, snow, darksandTaintedWater, space, empty, air, spawn, removeWall, removeOre, cliff, deepwater, water, taintedWater, deepTaintedWater, tar, slag, cryofluid, stone, craters, charr, sand, darksand, dirt, mud, ice, snow, darksandTaintedWater, space, empty,
dacite, rhyolite, rhyoliteCrater, roughRhyolite, regolith, yellowStone, redIce, redStone, denseRedStone, dacite, rhyolite, rhyoliteCrater, roughRhyolite, regolith, yellowStone, redIce, redStone, denseRedStone,
arkyciteFloor, arkyicStone, arkyciteFloor, arkyicStone,
redmat, bluemat, redmat, bluemat,
@ -174,6 +174,10 @@ public class Blocks{
spawn = new SpawnBlock("spawn"); spawn = new SpawnBlock("spawn");
removeWall = new RemoveWall("remove-wall");
removeOre = new RemoveOre("remove-ore");
cliff = new Cliff("cliff"){{ cliff = new Cliff("cliff"){{
inEditor = false; inEditor = false;
saveData = true; saveData = true;

View File

@ -715,7 +715,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
private void addBlockSelection(Table cont){ private void addBlockSelection(Table cont){
blockSelection = new Table(); blockSelection = new Table();
pane = new ScrollPane(blockSelection); pane = new ScrollPane(blockSelection, Styles.smallPane);
pane.setFadeScrollBars(false); pane.setFadeScrollBars(false);
pane.setOverscroll(true, false); pane.setOverscroll(true, false);
pane.exited(() -> { pane.exited(() -> {
@ -732,7 +732,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
cont.row(); cont.row();
cont.table(Tex.underline, extra -> extra.labelWrap(() -> editor.drawBlock.localizedName).width(200f).center()).growX(); cont.table(Tex.underline, extra -> extra.labelWrap(() -> editor.drawBlock.localizedName).width(200f).center()).growX();
cont.row(); cont.row();
cont.add(pane).expandY().top().left(); cont.add(pane).expandY().growX().top().left();
rebuildBlockSelection(""); rebuildBlockSelection("");
} }
@ -762,7 +762,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|| (!searchText.isEmpty() && !block.localizedName.toLowerCase().contains(searchText.toLowerCase())) || (!searchText.isEmpty() && !block.localizedName.toLowerCase().contains(searchText.toLowerCase()))
) continue; ) continue;
ImageButton button = new ImageButton(Tex.whiteui, Styles.squareTogglei); ImageButton button = new ImageButton(Tex.whiteui, Styles.clearNoneTogglei);
button.getStyle().imageUp = new TextureRegionDrawable(region); button.getStyle().imageUp = new TextureRegionDrawable(region);
button.clicked(() -> editor.drawBlock = block); button.clicked(() -> editor.drawBlock = block);
button.resizeImage(8 * 4f); button.resizeImage(8 * 4f);
@ -771,7 +771,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
if(i == 0) editor.drawBlock = block; if(i == 0) editor.drawBlock = block;
if(++i % 4 == 0){ if(++i % 6 == 0){
blockSelection.row(); blockSelection.row();
} }
} }

View File

@ -265,11 +265,11 @@ public class MobileInput extends InputHandler implements GestureListener{
}).name("confirmplace"); }).name("confirmplace");
} }
boolean showCancel(){ public boolean showCancel(){
return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem(); return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchematic();
} }
boolean hasSchem(){ public boolean hasSchematic(){
return lastSchematic != null && !selectPlans.isEmpty(); return lastSchematic != null && !selectPlans.isEmpty();
} }
@ -290,7 +290,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}); });
group.fill(t -> { group.fill(t -> {
t.visible(() -> !showCancel() && block == null && !hasSchem()); t.visible(() -> !showCancel() && block == null && !hasSchematic() && !state.rules.editor);
t.bottom().left(); t.bottom().left();
t.button("@command.queue", Icon.rightOpen, Styles.clearTogglet, () -> { t.button("@command.queue", Icon.rightOpen, Styles.clearTogglet, () -> {
@ -310,7 +310,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}); });
group.fill(t -> { group.fill(t -> {
t.visible(this::hasSchem); t.visible(this::hasSchematic);
t.bottom().left(); t.bottom().left();
t.table(Tex.pane, b -> { t.table(Tex.pane, b -> {
b.defaults().size(50f); b.defaults().size(50f);
@ -759,7 +759,7 @@ public class MobileInput extends InputHandler implements GestureListener{
payloadTarget = null; payloadTarget = null;
} }
if(locked || block != null || scene.hasField() || hasSchem() || selectPlans.size > 0){ if(locked || block != null || scene.hasField() || hasSchematic() || selectPlans.size > 0){
commandMode = false; commandMode = false;
} }

View File

@ -64,7 +64,7 @@ public class CrashHandler{
//don't create crash logs for custom builds, as it's expected //don't create crash logs for custom builds, as it's expected
if(OS.username.equals("anuke") && !"steam".equals(Version.modifier)){ if(OS.username.equals("anuke") && !"steam".equals(Version.modifier)){
// System.exit(1); System.exit(1);
} }
//attempt to load version regardless //attempt to load version regardless

View File

@ -14,6 +14,7 @@ import arc.scene.ui.ImageButton.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
@ -27,8 +28,11 @@ import mindustry.input.*;
import mindustry.net.Packets.*; import mindustry.net.Packets.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.storage.*; import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
import static mindustry.gen.Tex.*; import static mindustry.gen.Tex.*;
@ -49,6 +53,80 @@ public class HudFragment{
private Table lastUnlockLayout; private Table lastUnlockLayout;
private long lastToast; private long lastToast;
private Seq<Block> blocksOut = new Seq<>();
private void addBlockSelection(Table cont){
Table blockSelection = new Table();
var pane = new ScrollPane(blockSelection, Styles.smallPane);
pane.setFadeScrollBars(false);
Planet[] last = {state.rules.planet};
pane.update(() -> {
if(pane.hasScroll()){
Element result = Core.scene.getHoverElement();
if(result == null || !result.isDescendantOf(pane)){
Core.scene.setScrollFocus(null);
}
}
if(state.rules.planet != last[0]){
last[0] = state.rules.planet;
rebuildBlockSelection(blockSelection, "");
}
});
cont.table(search -> {
search.image(Icon.zoom).padRight(8);
search.field("", text -> rebuildBlockSelection(blockSelection, text)).growX()
.name("editor/search").maxTextLength(maxNameLength).get().setMessageText("@players.search");
}).growX().pad(-2).padLeft(6f);
cont.row();
cont.add(pane).expandY().top().left();
rebuildBlockSelection(blockSelection, "");
}
private void rebuildBlockSelection(Table blockSelection, String searchText){
blockSelection.clear();
blocksOut.clear();
blocksOut.addAll(Vars.content.blocks());
blocksOut.sort((b1, b2) -> {
int synth = Boolean.compare(b1.synthetic(), b2.synthetic());
if(synth != 0) return synth;
int ore = Boolean.compare(b1 instanceof OverlayFloor && b1 != Blocks.removeOre, b2 instanceof OverlayFloor && b2 != Blocks.removeOre);
if(ore != 0) return ore;
return Integer.compare(b1.id, b2.id);
});
int i = 0;
for(Block block : blocksOut){
TextureRegion region = block.uiIcon;
if(!Core.atlas.isFound(region)
|| (!block.inEditor && !(block instanceof RemoveWall) && !(block instanceof RemoveOre))
|| !block.isOnPlanet(state.rules.planet)
|| block.buildVisibility == BuildVisibility.debugOnly
|| (!searchText.isEmpty() && !block.localizedName.toLowerCase().contains(searchText.toLowerCase()))
) continue;
ImageButton button = new ImageButton(Tex.whiteui, Styles.clearNoneTogglei);
button.getStyle().imageUp = new TextureRegionDrawable(region);
button.clicked(() -> control.input.block = block);
button.resizeImage(8 * 4f);
button.update(() -> button.setChecked(control.input.block == block));
blockSelection.add(button).size(48f).tooltip(block.localizedName);
if(++i % 6 == 0){
blockSelection.row();
}
}
if(i == 0){
blockSelection.add("@none.found").padLeft(54f).padTop(10f);
}
}
public void build(Group parent){ public void build(Group parent){
//warn about guardian/boss waves //warn about guardian/boss waves
@ -247,26 +325,38 @@ public class HudFragment{
editorMain.name = "editor"; editorMain.name = "editor";
editorMain.table(Tex.buttonEdge4, t -> { editorMain.table(Tex.buttonEdge4, t -> {
//t.margin(0f);
t.name = "teams"; t.name = "teams";
t.add("@editor.teams").growX().left(); t.top().table(teams -> {
t.row();
t.table(teams -> {
teams.left(); teams.left();
int i = 0; int i = 0;
for(Team team : Team.baseTeams){ for(Team team : Team.baseTeams){
ImageButton button = teams.button(Tex.whiteui, Styles.clearNoneTogglei, 40f, () -> Call.setPlayerTeamEditor(player, team)) ImageButton button = teams.button(Tex.whiteui, Styles.clearNoneTogglei, 38f, () -> Call.setPlayerTeamEditor(player, team))
.size(50f).margin(6f).get(); .size(50f).margin(6f).get();
button.getImageCell().grow(); button.getImageCell().grow();
button.getStyle().imageUpColor = team.color; button.getStyle().imageUpColor = team.color;
button.update(() -> button.setChecked(player.team() == team)); button.update(() -> button.setChecked(player.team() == team));
if(++i % 3 == 0){ if(++i % 6 == 0){
teams.row(); teams.row();
} }
} }
}).left(); }).top().left();
t.row();
t.table(blocks -> {
addBlockSelection(blocks);
}).fillX().left();
}).width(dsize * 5 + 4f); }).width(dsize * 5 + 4f);
if(mobile){
editorMain.row().spacerY(() -> {
if(control.input instanceof MobileInput mob){
if(mob.hasSchematic()) return 156f;
if(mob.showCancel()) return 50f;
}
return 0f;
});
}
editorMain.visible(() -> shown && state.isEditor()); editorMain.visible(() -> shown && state.isEditor());
//fps display //fps display

View File

@ -920,6 +920,11 @@ public class Block extends UnlockableContent implements Senseable{
placeBegan(tile, previous); placeBegan(tile, previous);
} }
/** Called when building of this block ends. */
public void placeEnded(Tile tile, @Nullable Unit builder){
}
/** Called right before building of this block begins. */ /** Called right before building of this block begins. */
public void beforePlaceBegan(Tile tile, Block previous){ public void beforePlaceBegan(Tile tile, Block previous){

View File

@ -199,6 +199,10 @@ public class Build{
if(tile == null) return false; if(tile == null) return false;
if(!type.canPlaceOn(tile, team, rotation)){
return false;
}
//floors have different checks //floors have different checks
if(type.isFloor()){ if(type.isFloor()){
return type.isOverlay() ? tile.overlay() != type : tile.floor() != type; return type.isOverlay() ? tile.overlay() != type : tile.floor() != type;
@ -213,10 +217,6 @@ public class Build{
return false; return false;
} }
if(!type.canPlaceOn(tile, team, rotation)){
return false;
}
int offsetx = -(type.size - 1) / 2; int offsetx = -(type.size - 1) / 2;
int offsety = -(type.size - 1) / 2; int offsety = -(type.size - 1) / 2;

View File

@ -110,6 +110,8 @@ public class ConstructBlock extends Block{
if(shouldPlay()) block.placeSound.at(tile, block.placePitchChange ? calcPitch(true) : 1f); if(shouldPlay()) block.placeSound.at(tile, block.placePitchChange ? calcPitch(true) : 1f);
} }
block.placeEnded(tile, builder);
Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config)); Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config));
} }

View File

@ -0,0 +1,51 @@
package mindustry.world.blocks.environment;
import arc.graphics.g2d.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
public class RemoveOre extends OverlayFloor{
public RemoveOre(String name){
super(name);
allowRectanglePlacement = true;
placeEffect = Fx.rotateBlock;
instantBuild = true;
ignoreBuildDarkness = true;
placeableLiquid = true;
inEditor = false;
variants = 0;
}
@Override
public void drawPlan(BuildPlan plan, Eachable<BuildPlan> list, boolean valid, float alpha){
Draw.reset();
Draw.alpha(alpha * (valid ? 1f : 0.2f));
float prevScale = Draw.scl;
Draw.scl *= plan.animScale;
drawPlanRegion(plan, list);
Draw.scl = prevScale;
Draw.reset();
}
@Override
public boolean canPlaceOn(Tile tile, Team team, int rotation){
return tile.overlay() != Blocks.air;
}
@Override
public boolean canReplace(Block other){
return true;
}
@Override
public void placeEnded(Tile tile, @Nullable Unit builder){
tile.setOverlay(Blocks.air);
}
}

View File

@ -0,0 +1,50 @@
package mindustry.world.blocks.environment;
import arc.graphics.g2d.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
public class RemoveWall extends Block{
public RemoveWall(String name){
super(name);
allowRectanglePlacement = true;
placeEffect = Fx.rotateBlock;
instantBuild = true;
ignoreBuildDarkness = true;
placeableLiquid = true;
inEditor = false;
}
@Override
public void drawPlan(BuildPlan plan, Eachable<BuildPlan> list, boolean valid, float alpha){
Draw.reset();
Draw.alpha(alpha * (valid ? 1f : 0.2f));
float prevScale = Draw.scl;
Draw.scl *= plan.animScale;
drawPlanRegion(plan, list);
Draw.scl = prevScale;
Draw.reset();
}
@Override
public boolean canPlaceOn(Tile tile, Team team, int rotation){
return tile.block() != Blocks.air;
}
@Override
public boolean canReplace(Block other){
return other != Blocks.air && !other.synthetic();
}
@Override
public void placeEnded(Tile tile, @Nullable Unit builder){
tile.setBlock(Blocks.air);
}
}

View File

@ -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=66ae776c9f archash=bf2ab4d045