mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-12-22 17:23:59 +07:00
In-game editor UI improvements
This commit is contained in:
parent
24daa1e933
commit
15ca672179
BIN
core/assets-raw/sprites/blocks/environment/remove-ore.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/remove-ore.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 B |
BIN
core/assets-raw/sprites/blocks/environment/remove-wall.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/remove-wall.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 253 B |
@ -1563,6 +1563,8 @@ block.graphite-press.name = Graphite Press
|
||||
block.multi-press.name = Multi-Press
|
||||
block.constructing = {0} [lightgray](Constructing)
|
||||
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-foundation.name = Core: Foundation
|
||||
block.core-nucleus.name = Core: Nucleus
|
||||
|
@ -588,3 +588,5 @@
|
||||
63094=cat|cat
|
||||
63093=world-switch|block-world-switch-ui
|
||||
63092=dynamic|status-dynamic-ui
|
||||
63091=remove-wall|block-remove-wall-ui
|
||||
63090=remove-ore|block-remove-ore-ui
|
||||
|
@ -43,7 +43,7 @@ public class Blocks{
|
||||
public static Block
|
||||
|
||||
//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,
|
||||
arkyciteFloor, arkyicStone,
|
||||
redmat, bluemat,
|
||||
@ -174,6 +174,10 @@ public class Blocks{
|
||||
|
||||
spawn = new SpawnBlock("spawn");
|
||||
|
||||
removeWall = new RemoveWall("remove-wall");
|
||||
|
||||
removeOre = new RemoveOre("remove-ore");
|
||||
|
||||
cliff = new Cliff("cliff"){{
|
||||
inEditor = false;
|
||||
saveData = true;
|
||||
|
@ -715,7 +715,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
|
||||
private void addBlockSelection(Table cont){
|
||||
blockSelection = new Table();
|
||||
pane = new ScrollPane(blockSelection);
|
||||
pane = new ScrollPane(blockSelection, Styles.smallPane);
|
||||
pane.setFadeScrollBars(false);
|
||||
pane.setOverscroll(true, false);
|
||||
pane.exited(() -> {
|
||||
@ -732,7 +732,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
cont.row();
|
||||
cont.table(Tex.underline, extra -> extra.labelWrap(() -> editor.drawBlock.localizedName).width(200f).center()).growX();
|
||||
cont.row();
|
||||
cont.add(pane).expandY().top().left();
|
||||
cont.add(pane).expandY().growX().top().left();
|
||||
|
||||
rebuildBlockSelection("");
|
||||
}
|
||||
@ -762,7 +762,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
|| (!searchText.isEmpty() && !block.localizedName.toLowerCase().contains(searchText.toLowerCase()))
|
||||
) continue;
|
||||
|
||||
ImageButton button = new ImageButton(Tex.whiteui, Styles.squareTogglei);
|
||||
ImageButton button = new ImageButton(Tex.whiteui, Styles.clearNoneTogglei);
|
||||
button.getStyle().imageUp = new TextureRegionDrawable(region);
|
||||
button.clicked(() -> editor.drawBlock = block);
|
||||
button.resizeImage(8 * 4f);
|
||||
@ -771,7 +771,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
|
||||
if(i == 0) editor.drawBlock = block;
|
||||
|
||||
if(++i % 4 == 0){
|
||||
if(++i % 6 == 0){
|
||||
blockSelection.row();
|
||||
}
|
||||
}
|
||||
|
@ -265,11 +265,11 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}).name("confirmplace");
|
||||
}
|
||||
|
||||
boolean showCancel(){
|
||||
return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchem();
|
||||
public boolean showCancel(){
|
||||
return !player.dead() && (player.unit().isBuilding() || block != null || mode == breaking || !selectPlans.isEmpty()) && !hasSchematic();
|
||||
}
|
||||
|
||||
boolean hasSchem(){
|
||||
public boolean hasSchematic(){
|
||||
return lastSchematic != null && !selectPlans.isEmpty();
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
});
|
||||
|
||||
group.fill(t -> {
|
||||
t.visible(() -> !showCancel() && block == null && !hasSchem());
|
||||
t.visible(() -> !showCancel() && block == null && !hasSchematic() && !state.rules.editor);
|
||||
t.bottom().left();
|
||||
|
||||
t.button("@command.queue", Icon.rightOpen, Styles.clearTogglet, () -> {
|
||||
@ -310,7 +310,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
});
|
||||
|
||||
group.fill(t -> {
|
||||
t.visible(this::hasSchem);
|
||||
t.visible(this::hasSchematic);
|
||||
t.bottom().left();
|
||||
t.table(Tex.pane, b -> {
|
||||
b.defaults().size(50f);
|
||||
@ -759,7 +759,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
payloadTarget = null;
|
||||
}
|
||||
|
||||
if(locked || block != null || scene.hasField() || hasSchem() || selectPlans.size > 0){
|
||||
if(locked || block != null || scene.hasField() || hasSchematic() || selectPlans.size > 0){
|
||||
commandMode = false;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class CrashHandler{
|
||||
|
||||
//don't create crash logs for custom builds, as it's expected
|
||||
if(OS.username.equals("anuke") && !"steam".equals(Version.modifier)){
|
||||
// System.exit(1);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
//attempt to load version regardless
|
||||
|
@ -14,6 +14,7 @@ import arc.scene.ui.ImageButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.GameState.*;
|
||||
@ -27,8 +28,11 @@ import mindustry.input.*;
|
||||
import mindustry.net.Packets.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
import mindustry.world.blocks.storage.*;
|
||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.gen.Tex.*;
|
||||
@ -49,6 +53,80 @@ public class HudFragment{
|
||||
private Table lastUnlockLayout;
|
||||
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){
|
||||
|
||||
//warn about guardian/boss waves
|
||||
@ -247,26 +325,38 @@ public class HudFragment{
|
||||
|
||||
editorMain.name = "editor";
|
||||
editorMain.table(Tex.buttonEdge4, t -> {
|
||||
//t.margin(0f);
|
||||
t.name = "teams";
|
||||
t.add("@editor.teams").growX().left();
|
||||
t.row();
|
||||
t.table(teams -> {
|
||||
t.top().table(teams -> {
|
||||
teams.left();
|
||||
int i = 0;
|
||||
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();
|
||||
button.getImageCell().grow();
|
||||
button.getStyle().imageUpColor = team.color;
|
||||
button.update(() -> button.setChecked(player.team() == team));
|
||||
|
||||
if(++i % 3 == 0){
|
||||
if(++i % 6 == 0){
|
||||
teams.row();
|
||||
}
|
||||
}
|
||||
}).left();
|
||||
}).top().left();
|
||||
|
||||
t.row();
|
||||
|
||||
t.table(blocks -> {
|
||||
addBlockSelection(blocks);
|
||||
}).fillX().left();
|
||||
}).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());
|
||||
|
||||
//fps display
|
||||
|
@ -920,6 +920,11 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
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. */
|
||||
public void beforePlaceBegan(Tile tile, Block previous){
|
||||
|
||||
|
@ -199,6 +199,10 @@ public class Build{
|
||||
|
||||
if(tile == null) return false;
|
||||
|
||||
if(!type.canPlaceOn(tile, team, rotation)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//floors have different checks
|
||||
if(type.isFloor()){
|
||||
return type.isOverlay() ? tile.overlay() != type : tile.floor() != type;
|
||||
@ -213,10 +217,6 @@ public class Build{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!type.canPlaceOn(tile, team, rotation)){
|
||||
return false;
|
||||
}
|
||||
|
||||
int offsetx = -(type.size - 1) / 2;
|
||||
int offsety = -(type.size - 1) / 2;
|
||||
|
||||
|
@ -110,6 +110,8 @@ public class ConstructBlock extends Block{
|
||||
if(shouldPlay()) block.placeSound.at(tile, block.placePitchChange ? calcPitch(true) : 1f);
|
||||
}
|
||||
|
||||
block.placeEnded(tile, builder);
|
||||
|
||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, false, config));
|
||||
}
|
||||
|
||||
|
51
core/src/mindustry/world/blocks/environment/RemoveOre.java
Normal file
51
core/src/mindustry/world/blocks/environment/RemoveOre.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
50
core/src/mindustry/world/blocks/environment/RemoveWall.java
Normal file
50
core/src/mindustry/world/blocks/environment/RemoveWall.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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=66ae776c9f
|
||||
archash=bf2ab4d045
|
||||
|
Loading…
Reference in New Issue
Block a user