Add in-world zone visualizer, note particles, scenario shuffle, and step editor

This commit is contained in:
rardog
2026-09-24 13:09:53 +03:00
parent fba6ffacd4
commit f72b01b68b
6 changed files with 295 additions and 13 deletions
@@ -61,8 +61,13 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
private SoundSettings localSettings = new SoundSettings();
private final List<ScenarioQueue.Step> sourceScenarioSteps = new ArrayList<>();
private final List<ScenarioQueue.Step> zoneScenarioSteps = new ArrayList<>();
public static SoundPlayerScreen activeScreen;
public static boolean showZoneVisualizer = true;
private boolean sourceScenarioLoop;
private boolean zoneScenarioLoop;
private boolean sourceScenarioShuffle;
private boolean zoneScenarioShuffle;
private boolean editingZoneScenario;
private boolean sourceEnabled = true;
private boolean zoneEnabled = true;
@@ -123,6 +128,7 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
private Button zoneStopOnExitButton;
private Button zoneUseCustomCoordsButton;
private Button myPosButton;
private Button zoneVisualizerButton;
private TextFieldWidget zoneRadiusField;
private TextFieldWidget zoneBoxXField;
private TextFieldWidget zoneBoxYField;
@@ -134,9 +140,11 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
// Controls - Scenario
private Button scenarioTargetButton;
private Button scenarioLoopButton;
private Button scenarioShuffleButton;
private TextFieldWidget scenarioSoundField;
private TextFieldWidget scenarioDelayField;
private Button scenarioUseCurrentBtn;
private Button scenarioSetButton;
private Button scenarioAddButton;
private Button scenarioRemoveButton;
private Button scenarioUpButton;
@@ -195,9 +203,11 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
this.sourceScenarioSteps.clear();
this.sourceScenarioSteps.addAll(tile.getScenario().steps);
this.sourceScenarioLoop = tile.getScenario().loop;
this.sourceScenarioShuffle = tile.getScenario().shuffle;
this.zoneScenarioSteps.clear();
this.zoneScenarioSteps.addAll(tile.getZoneScenario().steps);
this.zoneScenarioLoop = tile.getZoneScenario().loop;
this.zoneScenarioShuffle = tile.getZoneScenario().shuffle;
this.sourceEnabled = tile.isSourceEnabled();
this.zoneEnabled = tile.isZoneEnabled();
this.wizardCompleted = tile.isWizardCompleted();
@@ -214,6 +224,7 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
this.zoneSourceY = tile.getZoneSourceY();
this.zoneSourceZ = tile.getZoneSourceZ();
}
activeScreen = this;
this.initFieldsAndButtons();
this.addTabButtons();
@@ -363,6 +374,10 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
this.zoneBoxXField = this.createField(x + 18, y + 68, 42, this.floatText(this.zoneBoxX, 1));
this.zoneBoxYField = this.createField(x + 78, y + 68, 42, this.floatText(this.zoneBoxY, 1));
this.zoneBoxZField = this.createField(x + 138, y + 68, 42, this.floatText(this.zoneBoxZ, 1));
this.zoneVisualizerButton = this.addButtonTracked(new Button(x + 150, y + 68, 100, 20, this.boolLabel("Вид в мире", showZoneVisualizer), b -> {
showZoneVisualizer = !showZoneVisualizer;
b.setMessage(this.boolLabel("Вид в мире", showZoneVisualizer));
}), this.zoneButtons);
this.zoneAutoStartButton = this.addButtonTracked(new Button(x, y + 94, 122, 20, this.boolLabel("Авто-вход", this.zoneAutoStartOnEnter), b -> {
this.zoneAutoStartOnEnter = !this.zoneAutoStartOnEnter;
@@ -389,23 +404,30 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
this.zoneSourceZField = this.createField(x + 178, y + 146, 58, Integer.toString(this.zoneSourceZ));
// --- TAB 5: SCENARIO ---
this.scenarioTargetButton = this.addButtonTracked(new Button(x, y + 42, 122, 20, new StringTextComponent(this.editingZoneScenario ? "Шаги: Зона" : "Шаги: Источник"), b -> {
this.scenarioTargetButton = this.addButtonTracked(new Button(x, y + 42, 78, 20, new StringTextComponent(this.editingZoneScenario ? "Шаги: Зона" : "Шаги: Блок"), b -> {
this.editingZoneScenario = !this.editingZoneScenario;
b.setMessage(new StringTextComponent(this.editingZoneScenario ? "Шаги: Зона" : "Шаги: Источник"));
b.setMessage(new StringTextComponent(this.editingZoneScenario ? "Шаги: Зона" : "Шаги: Блок"));
this.selectedScenarioIndex = -1;
this.scenarioLoopButton.setMessage(this.boolLabel("Цикл очереди", this.activeScenarioLoop()));
this.scenarioLoopButton.setMessage(this.boolLabel("Цикл", this.activeScenarioLoop()));
this.scenarioShuffleButton.setMessage(this.boolLabel("Случайно", this.activeScenarioShuffle()));
}), this.scenarioButtons);
this.scenarioLoopButton = this.addButtonTracked(new Button(x + 126, y + 42, 124, 20, this.boolLabel("Цикл очереди", this.activeScenarioLoop()), b -> {
this.scenarioLoopButton = this.addButtonTracked(new Button(x + 80, y + 42, 84, 20, this.boolLabel("Цикл", this.activeScenarioLoop()), b -> {
this.setActiveScenarioLoop(!this.activeScenarioLoop());
b.setMessage(this.boolLabel("Цикл очереди", this.activeScenarioLoop()));
b.setMessage(this.boolLabel("Цикл", this.activeScenarioLoop()));
}), this.scenarioButtons);
this.scenarioSoundField = this.createField(x, y + 70, 126, "");
this.scenarioUseCurrentBtn = this.addButtonTracked(new Button(x + 130, y + 69, 54, 20, new StringTextComponent("Текущ."), b -> {
this.scenarioShuffleButton = this.addButtonTracked(new Button(x + 166, y + 42, 84, 20, this.boolLabel("Случайно", this.activeScenarioShuffle()), b -> {
this.setActiveScenarioShuffle(!this.activeScenarioShuffle());
b.setMessage(this.boolLabel("Случайно", this.activeScenarioShuffle()));
}), this.scenarioButtons);
this.scenarioSoundField = this.createField(x, y + 70, 116, "");
this.scenarioUseCurrentBtn = this.addButtonTracked(new Button(x + 118, y + 69, 44, 20, new StringTextComponent("Тек."), b -> {
this.scenarioSoundField.setValue(this.soundIdField.getValue().trim());
}), this.scenarioButtons);
this.scenarioDelayField = this.createField(x + 192, y + 70, 58, "20");
this.scenarioDelayField = this.createField(x + 164, y + 70, 38, "20");
this.scenarioSetButton = this.addButtonTracked(new Button(x + 204, y + 69, 46, 20, new StringTextComponent("Задать"), b -> this.updateSelectedScenarioStep()), this.scenarioButtons);
this.scenarioAddButton = this.addButtonTracked(new Button(x, y + 96, 60, 20, new StringTextComponent("+ Шаг"), b -> this.addScenarioStep()), this.scenarioButtons);
this.scenarioRemoveButton = this.addButtonTracked(new Button(x + 64, y + 96, 60, 20, new StringTextComponent("- Шаг"), b -> this.removeScenarioStep()), this.scenarioButtons);
@@ -597,10 +619,12 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
payload.put("settings", (INBT) this.localSettings.toNbt());
ScenarioQueue sourceQ = new ScenarioQueue();
sourceQ.loop = this.sourceScenarioLoop;
sourceQ.shuffle = this.sourceScenarioShuffle;
sourceQ.steps.addAll(this.sourceScenarioSteps);
payload.put("scenario", (INBT) sourceQ.toNbt());
ScenarioQueue zoneQ = new ScenarioQueue();
zoneQ.loop = this.zoneScenarioLoop;
zoneQ.shuffle = this.zoneScenarioShuffle;
zoneQ.steps.addAll(this.zoneScenarioSteps);
payload.put("zoneScenario", (INBT) zoneQ.toNbt());
payload.putBoolean("sourceEnabled", this.sourceEnabled);
@@ -646,10 +670,12 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
this.sourceScenarioSteps.clear();
this.sourceScenarioSteps.addAll(sourceQ.steps);
this.sourceScenarioLoop = sourceQ.loop;
this.sourceScenarioShuffle = sourceQ.shuffle;
ScenarioQueue zoneQ = ScenarioQueue.fromNbt(payload.getCompound("zoneScenario"));
this.zoneScenarioSteps.clear();
this.zoneScenarioSteps.addAll(zoneQ.steps);
this.zoneScenarioLoop = zoneQ.loop;
this.zoneScenarioShuffle = zoneQ.shuffle;
this.sourceEnabled = payload.contains("sourceEnabled") && payload.getBoolean("sourceEnabled");
this.zoneEnabled = payload.contains("zoneEnabled") && payload.getBoolean("zoneEnabled");
this.wizardCompleted = payload.getBoolean("wizardCompleted");
@@ -769,6 +795,70 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
}
}
private boolean activeScenarioShuffle() {
return this.editingZoneScenario ? this.zoneScenarioShuffle : this.sourceScenarioShuffle;
}
private void setActiveScenarioShuffle(boolean shuffle) {
if (this.editingZoneScenario) {
this.zoneScenarioShuffle = shuffle;
} else {
this.sourceScenarioShuffle = shuffle;
}
}
private void updateSelectedScenarioStep() {
List<ScenarioQueue.Step> list = this.activeScenarioList();
if (this.selectedScenarioIndex >= 0 && this.selectedScenarioIndex < list.size()) {
String sid = this.scenarioSoundField.getValue().trim();
if (!sid.isEmpty()) {
int delay = this.clampInt(this.parseInt(this.scenarioDelayField.getValue(), 20), 0, 36000);
list.set(this.selectedScenarioIndex, new ScenarioQueue.Step(sid, delay));
this.saveAndSend(false, false);
}
}
}
public BlockPos getBlockPos() {
return this.menu != null ? this.menu.getPos() : null;
}
public ZoneShape getZoneShape() {
return this.zoneShape;
}
public float getZoneRadius() {
return this.zoneRadius;
}
public float getZoneBoxX() {
return this.zoneBoxX;
}
public float getZoneBoxY() {
return this.zoneBoxY;
}
public float getZoneBoxZ() {
return this.zoneBoxZ;
}
public boolean isZoneCustomCoords() {
return this.zoneUseCustomCoords;
}
public int getZoneSourceX() {
return this.zoneSourceX;
}
public int getZoneSourceY() {
return this.zoneSourceY;
}
public int getZoneSourceZ() {
return this.zoneSourceZ;
}
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
boolean enter = keyCode == 257 || keyCode == 335;
List<SoundManifestEntry> suggestions = this.filteredSoundEntries();
@@ -838,6 +928,9 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
int ry = listY + i * 14;
if (mouseX >= listX && mouseX <= (listX + 242) && mouseY >= ry && mouseY < (ry + 14)) {
this.selectedScenarioIndex = idx;
ScenarioQueue.Step step = list.get(idx);
this.scenarioSoundField.setValue(step.soundId);
this.scenarioDelayField.setValue(Integer.toString(step.delayTicks));
return true;
}
}
@@ -872,12 +965,24 @@ public class SoundPlayerScreen extends ContainerScreen<SoundPlayerContainer> {
return super.mouseScrolled(mouseX, mouseY, delta);
}
@Override
public void onClose() {
if (activeScreen == this) {
activeScreen = null;
}
AudioPlaybackService.get().stop("gui_preview");
this.saveAndSend(false, false);
super.onClose();
}
@Override
public void removed() {
if (activeScreen == this) {
activeScreen = null;
}
super.removed();
}
protected void renderBg(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) {
int x1 = this.leftPos;
int y1 = this.topPos;