Add in-world zone visualizer, note particles, scenario shuffle, and step editor
This commit is contained in:
@@ -55,6 +55,7 @@ public final class ClientHooks {
|
||||
@SubscribeEvent
|
||||
public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||
DebugOverlayRenderer.render(event.getMatrixStack(), event.getPartialTicks());
|
||||
com.example.soundmod.client.render.ZoneWorldRenderer.render(event.getMatrixStack(), event.getPartialTicks());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.example.soundmod.client.render;
|
||||
|
||||
import com.example.soundmod.client.screen.SoundPlayerScreen;
|
||||
import com.example.soundmod.common.ZoneShape;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Matrix3f;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
|
||||
public final class ZoneWorldRenderer {
|
||||
private ZoneWorldRenderer() {}
|
||||
|
||||
public static void render(MatrixStack stack, float partialTicks) {
|
||||
SoundPlayerScreen screen = SoundPlayerScreen.activeScreen;
|
||||
if (screen == null || !SoundPlayerScreen.showZoneVisualizer) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.player == null || mc.level == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos blockPos = screen.getBlockPos();
|
||||
if (blockPos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3d camera = mc.gameRenderer.getMainCamera().getPosition();
|
||||
IRenderTypeBuffer.Impl bufferSource = mc.renderBuffers().bufferSource();
|
||||
IVertexBuilder lineBuilder = bufferSource.getBuffer(RenderType.lines());
|
||||
|
||||
// 1. Highlight the edited block itself (soft gold)
|
||||
double bx = blockPos.getX() - camera.x;
|
||||
double by = blockPos.getY() - camera.y;
|
||||
double bz = blockPos.getZ() - camera.z;
|
||||
AxisAlignedBB blockBox = new AxisAlignedBB(bx, by, bz, bx + 1.0, by + 1.0, bz + 1.0);
|
||||
WorldRenderer.renderLineBox(stack, lineBuilder, blockBox, 1.0f, 0.85f, 0.2f, 0.9f);
|
||||
|
||||
// 2. Zone center
|
||||
double cx;
|
||||
double cy;
|
||||
double cz;
|
||||
if (screen.isZoneCustomCoords()) {
|
||||
cx = (double) screen.getZoneSourceX() + 0.5 - camera.x;
|
||||
cy = (double) screen.getZoneSourceY() + 0.5 - camera.y;
|
||||
cz = (double) screen.getZoneSourceZ() + 0.5 - camera.z;
|
||||
// Draw connecting line from block center to custom center
|
||||
drawLine(stack, lineBuilder, bx + 0.5, by + 0.5, bz + 0.5, cx, cy, cz, 1.0f, 0.6f, 0.1f, 0.85f);
|
||||
} else {
|
||||
cx = bx + 0.5;
|
||||
cy = by + 0.5;
|
||||
cz = bz + 0.5;
|
||||
}
|
||||
|
||||
// 3. Render Zone depending on shape
|
||||
if (screen.getZoneShape() == ZoneShape.SPHERE) {
|
||||
float radius = Math.max(0.5f, screen.getZoneRadius());
|
||||
// Equatorial and vertical rings in cyan
|
||||
drawCircleRing(stack, lineBuilder, cx, cy, cz, radius, 0, 0.2f, 0.85f, 1.0f, 0.95f);
|
||||
drawCircleRing(stack, lineBuilder, cx, cy, cz, radius, 1, 0.2f, 0.85f, 1.0f, 0.75f);
|
||||
drawCircleRing(stack, lineBuilder, cx, cy, cz, radius, 2, 0.2f, 0.85f, 1.0f, 0.75f);
|
||||
|
||||
// Bounding box around the sphere (light translucent)
|
||||
AxisAlignedBB sphereBox = new AxisAlignedBB(cx - radius, cy - radius, cz - radius, cx + radius, cy + radius, cz + radius);
|
||||
WorldRenderer.renderLineBox(stack, lineBuilder, sphereBox, 0.15f, 0.6f, 0.9f, 0.4f);
|
||||
} else {
|
||||
// BOX shape
|
||||
float hx = Math.max(0.5f, screen.getZoneBoxX());
|
||||
float hy = Math.max(0.5f, screen.getZoneBoxY());
|
||||
float hz = Math.max(0.5f, screen.getZoneBoxZ());
|
||||
AxisAlignedBB zoneBox = new AxisAlignedBB(cx - hx, cy - hy, cz - hz, cx + hx, cy + hy, cz + hz);
|
||||
WorldRenderer.renderLineBox(stack, lineBuilder, zoneBox, 0.25f, 1.0f, 0.5f, 0.95f);
|
||||
}
|
||||
|
||||
bufferSource.endBatch(RenderType.lines());
|
||||
}
|
||||
|
||||
private static void drawCircleRing(MatrixStack stack, IVertexBuilder builder, double cx, double cy, double cz, double r, int plane, float red, float green, float blue, float alpha) {
|
||||
int segments = 36;
|
||||
for (int i = 0; i < segments; i++) {
|
||||
double a1 = (i * 2.0 * Math.PI) / segments;
|
||||
double a2 = ((i + 1) * 2.0 * Math.PI) / segments;
|
||||
double x1;
|
||||
double y1;
|
||||
double z1;
|
||||
double x2;
|
||||
double y2;
|
||||
double z2;
|
||||
if (plane == 0) {
|
||||
x1 = cx + Math.cos(a1) * r;
|
||||
y1 = cy;
|
||||
z1 = cz + Math.sin(a1) * r;
|
||||
x2 = cx + Math.cos(a2) * r;
|
||||
y2 = cy;
|
||||
z2 = cz + Math.sin(a2) * r;
|
||||
} else if (plane == 1) {
|
||||
x1 = cx + Math.cos(a1) * r;
|
||||
y1 = cy + Math.sin(a1) * r;
|
||||
z1 = cz;
|
||||
x2 = cx + Math.cos(a2) * r;
|
||||
y2 = cy + Math.sin(a2) * r;
|
||||
z2 = cz;
|
||||
} else {
|
||||
x1 = cx;
|
||||
y1 = cy + Math.sin(a1) * r;
|
||||
z1 = cz + Math.cos(a1) * r;
|
||||
x2 = cx;
|
||||
y2 = cy + Math.sin(a2) * r;
|
||||
z2 = cz + Math.cos(a2) * r;
|
||||
}
|
||||
drawLine(stack, builder, x1, y1, z1, x2, y2, z2, red, green, blue, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawLine(MatrixStack stack, IVertexBuilder builder, double x1, double y1, double z1, double x2, double y2, double z2, float r, float g, float b, float a) {
|
||||
Matrix4f m = stack.last().pose();
|
||||
Matrix3f n = stack.last().normal();
|
||||
float dx = (float)(x2 - x1);
|
||||
float dy = (float)(y2 - y1);
|
||||
float dz = (float)(z2 - z1);
|
||||
float len = MathHelper.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
if (len > 1.0e-5f) {
|
||||
dx /= len;
|
||||
dy /= len;
|
||||
dz /= len;
|
||||
}
|
||||
builder.vertex(m, (float)x1, (float)y1, (float)z1).color(r, g, b, a).normal(n, dx, dy, dz).endVertex();
|
||||
builder.vertex(m, (float)x2, (float)y2, (float)z2).color(r, g, b, a).normal(n, dx, dy, dz).endVertex();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.minecraft.nbt.ListNBT;
|
||||
public class ScenarioQueue {
|
||||
public final List<Step> steps = new ArrayList<Step>();
|
||||
public boolean loop;
|
||||
public boolean shuffle;
|
||||
|
||||
public CompoundNBT toNbt() {
|
||||
CompoundNBT tag = new CompoundNBT();
|
||||
@@ -26,6 +27,7 @@ public class ScenarioQueue {
|
||||
}
|
||||
tag.put("steps", list);
|
||||
tag.putBoolean("loop", this.loop);
|
||||
tag.putBoolean("shuffle", this.shuffle);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -36,6 +38,7 @@ public class ScenarioQueue {
|
||||
queue.steps.add(Step.fromNbt(list.getCompound(i)));
|
||||
}
|
||||
queue.loop = tag.getBoolean("loop");
|
||||
queue.shuffle = tag.getBoolean("shuffle");
|
||||
return queue;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,17 @@
|
||||
*/
|
||||
package com.example.soundmod.gameplay.block;
|
||||
|
||||
import com.example.soundmod.client.audio.AudioPlaybackService;
|
||||
import com.example.soundmod.gameplay.tile.SoundPlayerTileEntity;
|
||||
import com.example.soundmod.registry.ModTileEntities;
|
||||
import java.util.Random;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
@@ -36,23 +39,27 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class SoundPlayerBlock
|
||||
extends Block {
|
||||
public class SoundPlayerBlock extends Block {
|
||||
public SoundPlayerBlock(AbstractBlock.Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return ((TileEntityType)ModTileEntities.SOUND_PLAYER_TILE.get()).create();
|
||||
}
|
||||
|
||||
public ActionResultType func_225533_a_(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
|
||||
@Override
|
||||
public ActionResultType use(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
|
||||
TileEntity te = world.getBlockEntity(pos);
|
||||
if (!world.isClientSide && te instanceof SoundPlayerTileEntity && player instanceof ServerPlayerEntity) {
|
||||
SoundPlayerTileEntity soundTe = (SoundPlayerTileEntity)te;
|
||||
@@ -62,14 +69,27 @@ extends Block {
|
||||
NetworkHooks.openGui((ServerPlayerEntity)((ServerPlayerEntity)player), (INamedContainerProvider)soundTe, (BlockPos)pos);
|
||||
}
|
||||
}
|
||||
return ActionResultType.sidedSuccess((boolean)world.isClientSide);
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
}
|
||||
|
||||
public void func_220069_a(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean moving) {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean moving) {
|
||||
TileEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof SoundPlayerTileEntity) {
|
||||
((SoundPlayerTileEntity)te).onRedstoneChanged(world.hasNeighborSignal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void animateTick(BlockState state, World world, BlockPos pos, Random rand) {
|
||||
if (world.isClientSide && AudioPlaybackService.get().isPlaying("sound_player:" + pos.asLong())) {
|
||||
double px = (double) pos.getX() + 0.5 + (rand.nextDouble() - 0.5) * 0.5;
|
||||
double py = (double) pos.getY() + 1.05 + rand.nextDouble() * 0.25;
|
||||
double pz = (double) pos.getZ() + 0.5 + (rand.nextDouble() - 0.5) * 0.5;
|
||||
double noteColor = (double) rand.nextInt(25) / 24.0;
|
||||
world.addParticle(ParticleTypes.NOTE, px, py, pz, noteColor, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -509,6 +509,21 @@ ITickableTileEntity {
|
||||
--this.scenarioWaitTicks;
|
||||
return;
|
||||
}
|
||||
if (this.scenario.shuffle) {
|
||||
int size = this.scenario.steps.size();
|
||||
int nextIdx = 0;
|
||||
if (size > 1) {
|
||||
do {
|
||||
nextIdx = this.level.random.nextInt(size);
|
||||
} while (nextIdx == this.scenarioStepIndex && this.level.random.nextFloat() > 0.15f);
|
||||
}
|
||||
this.scenarioStepIndex = nextIdx;
|
||||
ScenarioQueue.Step step = this.scenario.steps.get(nextIdx);
|
||||
this.scenarioWaitTicks = Math.max(0, step.delayTicks);
|
||||
this.emitScenarioStepPlay(step.soundId);
|
||||
this.setChanged();
|
||||
return;
|
||||
}
|
||||
if (this.scenarioStepIndex >= this.scenario.steps.size()) {
|
||||
if (this.scenario.loop) {
|
||||
this.scenarioStepIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user