Files
SoundPadMod/src/main/java/com/example/soundmod/gameplay/tile/SoundPlayerTileEntity.java
T

604 lines
28 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nullable
* net.minecraft.block.BlockState
* net.minecraft.entity.player.PlayerEntity
* net.minecraft.entity.player.PlayerInventory
* net.minecraft.entity.player.ServerPlayerEntity
* net.minecraft.inventory.container.Container
* net.minecraft.inventory.container.INamedContainerProvider
* net.minecraft.nbt.CompoundNBT
* net.minecraft.nbt.INBT
* net.minecraft.network.NetworkManager
* net.minecraft.network.play.server.SUpdateTileEntityPacket
* net.minecraft.tileentity.ITickableTileEntity
* net.minecraft.tileentity.TileEntity
* net.minecraft.tileentity.TileEntityType
* net.minecraft.util.math.BlockPos
* net.minecraft.util.math.vector.Vector3d
* net.minecraft.util.text.ITextComponent
* net.minecraft.util.text.TranslationTextComponent
* net.minecraftforge.fml.network.PacketDistributor
*/
package com.example.soundmod.gameplay.tile;
import com.example.soundmod.common.ActivationMode;
import com.example.soundmod.common.RedstoneMode;
import com.example.soundmod.common.ScenarioQueue;
import com.example.soundmod.common.SoundSettings;
import com.example.soundmod.common.ZoneIntersectionPolicy;
import com.example.soundmod.common.ZoneShape;
import com.example.soundmod.core.SoundDebug;
import com.example.soundmod.gameplay.container.SoundPlayerContainer;
import com.example.soundmod.net.NetworkHandler;
import com.example.soundmod.net.packet.S2CBlockStateSyncPacket;
import com.example.soundmod.net.packet.S2CPlaySoundPacket;
import com.example.soundmod.net.packet.S2CZoneStateSyncPacket;
import com.example.soundmod.registry.ModTileEntities;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.fml.network.PacketDistributor;
public class SoundPlayerTileEntity
extends TileEntity
implements INamedContainerProvider,
ITickableTileEntity {
private static final int MANUAL_CLICK_DEBOUNCE_TICKS = 6;
private static final Map<String, Long> MANUAL_CLICK_GUARD = new ConcurrentHashMap<String, Long>();
private SoundSettings settings = new SoundSettings();
private ScenarioQueue scenario = new ScenarioQueue();
private boolean redstonePowered;
private int timerTicks;
private boolean playing;
private int pendingStartTicks = -1;
private boolean scenarioRunning;
private int scenarioStepIndex;
private int scenarioWaitTicks;
private long lastPlayTick = Long.MIN_VALUE;
private long lastStopTick = Long.MIN_VALUE;
private boolean sourceEnabled = true;
private boolean zoneEnabled = true;
private boolean wizardCompleted;
private ZoneShape zoneShape = ZoneShape.SPHERE;
private float zoneRadius = 12.0f;
private Vector3d zoneBoxHalfExtents = new Vector3d(8.0, 4.0, 8.0);
private boolean zoneAutoStartOnEnter = true;
private boolean zoneStopOnExit = true;
private ZoneIntersectionPolicy zoneIntersectionPolicy = ZoneIntersectionPolicy.HIGHEST_PRIORITY;
private ScenarioQueue zoneScenario = new ScenarioQueue();
private boolean zoneUseCustomCoords;
private int zoneSourceX;
private int zoneSourceY;
private int zoneSourceZ;
public SoundPlayerTileEntity() {
super((TileEntityType)ModTileEntities.SOUND_PLAYER_TILE.get());
}
public SoundSettings getSettings() {
return this.settings;
}
public ScenarioQueue getScenario() {
return this.scenario;
}
public boolean isSourceEnabled() {
return this.sourceEnabled;
}
public boolean isZoneEnabled() {
return this.zoneEnabled;
}
public boolean isWizardCompleted() {
return this.wizardCompleted;
}
public ZoneShape getZoneShape() {
return this.zoneShape;
}
public float getZoneRadius() {
return this.zoneRadius;
}
public Vector3d getZoneBoxHalfExtents() {
return this.zoneBoxHalfExtents;
}
public boolean isZoneAutoStartOnEnter() {
return this.zoneAutoStartOnEnter;
}
public boolean isZoneStopOnExit() {
return this.zoneStopOnExit;
}
public ZoneIntersectionPolicy getZoneIntersectionPolicy() {
return this.zoneIntersectionPolicy;
}
public ScenarioQueue getZoneScenario() {
return this.zoneScenario;
}
public boolean isZoneUseCustomCoords() {
return this.zoneUseCustomCoords;
}
public int getZoneSourceX() {
return this.zoneSourceX;
}
public int getZoneSourceY() {
return this.zoneSourceY;
}
public int getZoneSourceZ() {
return this.zoneSourceZ;
}
public BlockPos getZoneSourcePos() {
if (this.zoneUseCustomCoords) {
return new BlockPos(this.zoneSourceX, this.zoneSourceY, this.zoneSourceZ);
}
return this.worldPosition;
}
public void updateFromClient(CompoundNBT payload) {
ActivationMode oldMode = this.settings.activationMode;
this.settings = SoundSettings.fromNbt(payload.getCompound("settings"));
this.scenario = ScenarioQueue.fromNbt(payload.getCompound("scenario"));
this.sourceEnabled = payload.contains("sourceEnabled") ? payload.getBoolean("sourceEnabled") : this.sourceEnabled;
this.zoneEnabled = payload.contains("zoneEnabled") ? payload.getBoolean("zoneEnabled") : this.zoneEnabled;
this.wizardCompleted = payload.contains("wizardCompleted") ? payload.getBoolean("wizardCompleted") : this.wizardCompleted;
this.zoneShape = this.parseZoneShape(payload.contains("zoneShape") ? payload.getString("zoneShape") : this.zoneShape.name());
this.zoneRadius = this.clampFloat(payload.contains("zoneRadius") ? payload.getFloat("zoneRadius") : this.zoneRadius, 1.0f, 256.0f);
double boxX = payload.contains("zoneBoxX") ? payload.getDouble("zoneBoxX") : this.zoneBoxHalfExtents.x;
double boxY = payload.contains("zoneBoxY") ? payload.getDouble("zoneBoxY") : this.zoneBoxHalfExtents.y;
double boxZ = payload.contains("zoneBoxZ") ? payload.getDouble("zoneBoxZ") : this.zoneBoxHalfExtents.z;
this.zoneBoxHalfExtents = new Vector3d(this.clampDouble(boxX, 0.5, 128.0), this.clampDouble(boxY, 0.5, 128.0), this.clampDouble(boxZ, 0.5, 128.0));
this.zoneAutoStartOnEnter = payload.contains("zoneAutoStartOnEnter") ? payload.getBoolean("zoneAutoStartOnEnter") : this.zoneAutoStartOnEnter;
this.zoneStopOnExit = payload.contains("zoneStopOnExit") ? payload.getBoolean("zoneStopOnExit") : this.zoneStopOnExit;
this.zoneIntersectionPolicy = this.parseZonePolicy(payload.contains("zoneIntersectionPolicy") ? payload.getString("zoneIntersectionPolicy") : this.zoneIntersectionPolicy.name());
if (payload.contains("zoneScenario")) {
this.zoneScenario = ScenarioQueue.fromNbt(payload.getCompound("zoneScenario"));
}
this.zoneUseCustomCoords = payload.contains("zoneUseCustomCoords") ? payload.getBoolean("zoneUseCustomCoords") : this.zoneUseCustomCoords;
this.zoneSourceX = payload.contains("zoneSourceX") ? payload.getInt("zoneSourceX") : this.zoneSourceX;
this.zoneSourceY = payload.contains("zoneSourceY") ? payload.getInt("zoneSourceY") : this.zoneSourceY;
int n = this.zoneSourceZ = payload.contains("zoneSourceZ") ? payload.getInt("zoneSourceZ") : this.zoneSourceZ;
if (this.level != null && !this.level.isClientSide) {
boolean powered = this.level.hasNeighborSignal(this.worldPosition);
if (this.settings.activationMode == ActivationMode.REDSTONE) {
if (oldMode != ActivationMode.REDSTONE) {
this.redstonePowered = false;
}
this.onRedstoneChanged(powered);
} else if (oldMode == ActivationMode.REDSTONE) {
this.redstonePowered = powered;
}
}
this.setChanged();
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "config updated soundId={} mode={} source={} zone={}", this.settings.soundId, this.settings.activationMode.name(), this.sourceEnabled, this.zoneEnabled);
this.sync();
}
public void onRedstoneChanged(boolean powered) {
if (!this.sourceEnabled) {
this.redstonePowered = powered;
return;
}
if (this.settings.activationMode == ActivationMode.REDSTONE) {
if (this.settings.redstoneMode == RedstoneMode.EDGE) {
if (powered && !this.redstonePowered) {
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=EDGE event=rising action=play soundId={}", this.settings.soundId);
this.play();
} else if (!powered && this.redstonePowered) {
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=EDGE event=falling action=none", new Object[0]);
}
} else if (powered && !this.redstonePowered) {
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=HOLD event=rising action=ensure_play soundId={}", this.settings.soundId);
this.play();
} else if (powered && !this.isSourceRuntimeActive()) {
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=HOLD event=steady_high action=rearm_play soundId={}", this.settings.soundId);
this.play();
} else if (!powered && this.redstonePowered && this.isSourceRuntimeActive()) {
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=HOLD event=falling action=stop", new Object[0]);
this.stop();
}
}
this.redstonePowered = powered;
}
public void play() {
if (!this.sourceEnabled) {
return;
}
if (this.level != null && !this.level.isClientSide) {
long now = this.level.getGameTime();
if (now == this.lastPlayTick) {
SoundDebug.log(SoundDebug.Level.L3, "TRIGGER", this.debugPosId(), "play suppressed duplicate tick={}", now);
return;
}
this.lastPlayTick = now;
this.pendingStartTicks = Math.max(0, this.settings.startDelayTicks);
if (!this.scenario.steps.isEmpty()) {
this.scenarioRunning = true;
this.scenarioStepIndex = 0;
this.scenarioWaitTicks = this.pendingStartTicks;
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "scenario start requested steps={} startDelay={}", this.scenario.steps.size(), this.pendingStartTicks);
} else {
this.scenarioRunning = false;
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "play scheduled sourceId=sound_player:{} soundId={} startDelay={}", this.worldPosition.asLong(), this.settings.soundId, this.pendingStartTicks);
}
if (this.pendingStartTicks == 0 && !this.scenarioRunning) {
this.emitPlayCurrentSettings();
this.pendingStartTicks = -1;
}
this.setChanged();
}
}
public void playFromClick(ServerPlayerEntity player) {
if (this.level == null || this.level.isClientSide) {
return;
}
long now = this.level.getGameTime();
String key = player.getUUID().toString() + ":" + this.worldPosition.asLong();
Long last = MANUAL_CLICK_GUARD.get(key);
if (last != null && now - last < 6L) {
SoundDebug.log(SoundDebug.Level.L3, "TRIGGER", this.debugPosId(), "click debounce suppress player={} dt={}", player.getScoreboardName(), now - last);
return;
}
MANUAL_CLICK_GUARD.put(key, now);
this.play();
}
public void stop() {
if (this.level != null && !this.level.isClientSide) {
long now = this.level.getGameTime();
if (now == this.lastStopTick) {
SoundDebug.log(SoundDebug.Level.L3, "TRIGGER", this.debugPosId(), "stop suppressed duplicate tick={}", now);
return;
}
this.lastStopTick = now;
this.playing = false;
this.pendingStartTicks = -1;
this.scenarioRunning = false;
this.scenarioStepIndex = 0;
this.scenarioWaitTicks = 0;
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "stop requested sourceId=sound_player:{}", this.worldPosition.asLong());
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), (Object)new S2CBlockStateSyncPacket(this.worldPosition, this.save(new CompoundNBT()), false));
this.setChanged();
this.notifyNeighbors();
}
}
public boolean isPlaying() {
return this.playing;
}
private void sync() {
if (this.level != null && !this.level.isClientSide) {
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), (Object)new S2CBlockStateSyncPacket(this.worldPosition, this.save(new CompoundNBT()), false));
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), (Object)new S2CZoneStateSyncPacket(this.worldPosition, this.createZoneSyncPayload()));
}
}
public CompoundNBT createZoneSyncPayload() {
CompoundNBT tag = new CompoundNBT();
tag.putBoolean("zoneEnabled", this.zoneEnabled);
tag.putBoolean("sourceEnabled", this.sourceEnabled);
tag.putBoolean("wizardCompleted", this.wizardCompleted);
tag.putString("zoneShape", this.zoneShape.name());
tag.putFloat("zoneRadius", this.zoneRadius);
tag.putDouble("zoneBoxX", this.zoneBoxHalfExtents.x);
tag.putDouble("zoneBoxY", this.zoneBoxHalfExtents.y);
tag.putDouble("zoneBoxZ", this.zoneBoxHalfExtents.z);
tag.putBoolean("zoneAutoStartOnEnter", this.zoneAutoStartOnEnter);
tag.putBoolean("zoneStopOnExit", this.zoneStopOnExit);
tag.putString("zoneIntersectionPolicy", this.zoneIntersectionPolicy.name());
tag.put("zoneScenario", (INBT)this.zoneScenario.toNbt());
tag.putBoolean("zoneUseCustomCoords", this.zoneUseCustomCoords);
tag.putInt("zoneSourceX", this.zoneSourceX);
tag.putInt("zoneSourceY", this.zoneSourceY);
tag.putInt("zoneSourceZ", this.zoneSourceZ);
return tag;
}
public void loadZoneSyncPayload(CompoundNBT tag) {
if (tag == null) {
return;
}
if (tag.contains("zoneEnabled")) {
this.zoneEnabled = tag.getBoolean("zoneEnabled");
}
if (tag.contains("sourceEnabled")) {
this.sourceEnabled = tag.getBoolean("sourceEnabled");
}
if (tag.contains("wizardCompleted")) {
this.wizardCompleted = tag.getBoolean("wizardCompleted");
}
if (tag.contains("zoneShape")) {
this.zoneShape = this.parseZoneShape(tag.getString("zoneShape"));
}
if (tag.contains("zoneRadius")) {
this.zoneRadius = this.clampFloat(tag.getFloat("zoneRadius"), 1.0f, 256.0f);
}
double bx = tag.contains("zoneBoxX") ? tag.getDouble("zoneBoxX") : this.zoneBoxHalfExtents.x;
double by = tag.contains("zoneBoxY") ? tag.getDouble("zoneBoxY") : this.zoneBoxHalfExtents.y;
double bz = tag.contains("zoneBoxZ") ? tag.getDouble("zoneBoxZ") : this.zoneBoxHalfExtents.z;
this.zoneBoxHalfExtents = new Vector3d(this.clampDouble(bx, 0.5, 128.0), this.clampDouble(by, 0.5, 128.0), this.clampDouble(bz, 0.5, 128.0));
if (tag.contains("zoneAutoStartOnEnter")) {
this.zoneAutoStartOnEnter = tag.getBoolean("zoneAutoStartOnEnter");
}
if (tag.contains("zoneStopOnExit")) {
this.zoneStopOnExit = tag.getBoolean("zoneStopOnExit");
}
if (tag.contains("zoneIntersectionPolicy")) {
this.zoneIntersectionPolicy = this.parseZonePolicy(tag.getString("zoneIntersectionPolicy"));
}
if (tag.contains("zoneScenario")) {
this.zoneScenario = ScenarioQueue.fromNbt(tag.getCompound("zoneScenario"));
}
if (tag.contains("zoneUseCustomCoords")) {
this.zoneUseCustomCoords = tag.getBoolean("zoneUseCustomCoords");
}
if (tag.contains("zoneSourceX")) {
this.zoneSourceX = tag.getInt("zoneSourceX");
}
if (tag.contains("zoneSourceY")) {
this.zoneSourceY = tag.getInt("zoneSourceY");
}
if (tag.contains("zoneSourceZ")) {
this.zoneSourceZ = tag.getInt("zoneSourceZ");
}
}
public CompoundNBT save(CompoundNBT tag) {
super.save(tag);
tag.put("settings", (INBT)this.settings.toNbt());
tag.put("scenario", (INBT)this.scenario.toNbt());
tag.putBoolean("redstonePowered", this.redstonePowered);
tag.putInt("timerTicks", this.timerTicks);
tag.putBoolean("playing", this.playing);
tag.putInt("pendingStartTicks", this.pendingStartTicks);
tag.putBoolean("scenarioRunning", this.scenarioRunning);
tag.putInt("scenarioStepIndex", this.scenarioStepIndex);
tag.putInt("scenarioWaitTicks", this.scenarioWaitTicks);
tag.putBoolean("sourceEnabled", this.sourceEnabled);
tag.putBoolean("zoneEnabled", this.zoneEnabled);
tag.putBoolean("wizardCompleted", this.wizardCompleted);
tag.putString("zoneShape", this.zoneShape.name());
tag.putFloat("zoneRadius", this.zoneRadius);
tag.putDouble("zoneBoxX", this.zoneBoxHalfExtents.x);
tag.putDouble("zoneBoxY", this.zoneBoxHalfExtents.y);
tag.putDouble("zoneBoxZ", this.zoneBoxHalfExtents.z);
tag.putBoolean("zoneAutoStartOnEnter", this.zoneAutoStartOnEnter);
tag.putBoolean("zoneStopOnExit", this.zoneStopOnExit);
tag.putString("zoneIntersectionPolicy", this.zoneIntersectionPolicy.name());
tag.put("zoneScenario", (INBT)this.zoneScenario.toNbt());
tag.putBoolean("zoneUseCustomCoords", this.zoneUseCustomCoords);
tag.putInt("zoneSourceX", this.zoneSourceX);
tag.putInt("zoneSourceY", this.zoneSourceY);
tag.putInt("zoneSourceZ", this.zoneSourceZ);
return tag;
}
public void load(BlockState state, CompoundNBT tag) {
super.load(state, tag);
this.settings = SoundSettings.fromNbt(tag.getCompound("settings"));
this.scenario = ScenarioQueue.fromNbt(tag.getCompound("scenario"));
this.redstonePowered = tag.getBoolean("redstonePowered");
this.timerTicks = tag.getInt("timerTicks");
this.playing = tag.getBoolean("playing");
this.pendingStartTicks = tag.contains("pendingStartTicks") ? tag.getInt("pendingStartTicks") : -1;
this.scenarioRunning = tag.getBoolean("scenarioRunning");
this.scenarioStepIndex = tag.getInt("scenarioStepIndex");
this.scenarioWaitTicks = tag.getInt("scenarioWaitTicks");
this.sourceEnabled = tag.contains("sourceEnabled") ? tag.getBoolean("sourceEnabled") : true;
this.zoneEnabled = tag.contains("zoneEnabled") ? tag.getBoolean("zoneEnabled") : true;
this.wizardCompleted = tag.getBoolean("wizardCompleted");
this.zoneShape = this.parseZoneShape(tag.contains("zoneShape") ? tag.getString("zoneShape") : ZoneShape.SPHERE.name());
this.zoneRadius = this.clampFloat(tag.contains("zoneRadius") ? tag.getFloat("zoneRadius") : 12.0f, 1.0f, 256.0f);
this.zoneBoxHalfExtents = new Vector3d(this.clampDouble(tag.contains("zoneBoxX") ? tag.getDouble("zoneBoxX") : 8.0, 0.5, 128.0), this.clampDouble(tag.contains("zoneBoxY") ? tag.getDouble("zoneBoxY") : 4.0, 0.5, 128.0), this.clampDouble(tag.contains("zoneBoxZ") ? tag.getDouble("zoneBoxZ") : 8.0, 0.5, 128.0));
this.zoneAutoStartOnEnter = tag.contains("zoneAutoStartOnEnter") ? tag.getBoolean("zoneAutoStartOnEnter") : true;
this.zoneStopOnExit = tag.contains("zoneStopOnExit") ? tag.getBoolean("zoneStopOnExit") : true;
this.zoneIntersectionPolicy = this.parseZonePolicy(tag.contains("zoneIntersectionPolicy") ? tag.getString("zoneIntersectionPolicy") : ZoneIntersectionPolicy.HIGHEST_PRIORITY.name());
this.zoneScenario = tag.contains("zoneScenario") ? ScenarioQueue.fromNbt(tag.getCompound("zoneScenario")) : new ScenarioQueue();
this.zoneUseCustomCoords = tag.contains("zoneUseCustomCoords") && tag.getBoolean("zoneUseCustomCoords");
this.zoneSourceX = tag.contains("zoneSourceX") ? tag.getInt("zoneSourceX") : this.worldPosition.getX();
this.zoneSourceY = tag.contains("zoneSourceY") ? tag.getInt("zoneSourceY") : this.worldPosition.getY();
this.zoneSourceZ = tag.contains("zoneSourceZ") ? tag.getInt("zoneSourceZ") : this.worldPosition.getZ();
}
public SUpdateTileEntityPacket getUpdatePacket() {
return new SUpdateTileEntityPacket(this.worldPosition, 0, this.getUpdateTag());
}
public CompoundNBT getUpdateTag() {
return this.save(new CompoundNBT());
}
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
this.load(this.getBlockState(), pkt.getTag());
}
public ITextComponent getDisplayName() {
return new TranslationTextComponent("screen.soundmod.sound_player");
}
@Nullable
public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity player) {
return new SoundPlayerContainer(windowId, this.level, this.worldPosition, playerInventory, player);
}
public void tick() {
if (this.level == null || this.level.isClientSide) {
return;
}
if (!this.sourceEnabled) {
if (this.playing) {
this.stop();
}
return;
}
if (this.settings.activationMode == ActivationMode.REDSTONE) {
boolean poweredNow = this.level.hasNeighborSignal(this.worldPosition);
if (poweredNow != this.redstonePowered) {
this.onRedstoneChanged(poweredNow);
} else if (this.settings.redstoneMode == RedstoneMode.HOLD && poweredNow && !this.isSourceRuntimeActive()) {
SoundDebug.log(SoundDebug.Level.L3, "TRIGGER", this.debugPosId(), "[REDSTONE] mode=HOLD event=tick_guard action=ensure_play", new Object[0]);
this.play();
}
}
if (this.settings.activationMode == ActivationMode.AUTO && !this.playing) {
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "auto mode trigger", new Object[0]);
this.play();
}
if (this.settings.activationMode == ActivationMode.TIMER) {
++this.timerTicks;
int interval = Math.max(20, this.settings.repeatDelayTicks <= 0 ? 20 : this.settings.repeatDelayTicks);
if (this.timerTicks >= interval) {
this.timerTicks = 0;
SoundDebug.log(SoundDebug.Level.L2, "TRIGGER", this.debugPosId(), "timer trigger interval={}", interval);
this.play();
}
}
if (this.pendingStartTicks >= 0 && !this.scenarioRunning) {
if (this.pendingStartTicks == 0) {
this.emitPlayCurrentSettings();
this.pendingStartTicks = -1;
this.setChanged();
} else {
--this.pendingStartTicks;
}
}
if (this.scenarioRunning) {
this.tickScenario();
}
}
private void tickScenario() {
if (this.scenario.steps.isEmpty()) {
this.scenarioRunning = false;
return;
}
if (this.scenarioWaitTicks > 0) {
--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;
} else {
this.scenarioRunning = false;
return;
}
}
ScenarioQueue.Step step = this.scenario.steps.get(this.scenarioStepIndex);
++this.scenarioStepIndex;
this.scenarioWaitTicks = Math.max(0, step.delayTicks);
this.emitScenarioStepPlay(step.soundId);
this.setChanged();
}
private void emitPlayCurrentSettings() {
this.playing = true;
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "play requested sourceId=sound_player:{} soundId={}", this.worldPosition.asLong(), this.settings.soundId);
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), (Object)new S2CBlockStateSyncPacket(this.worldPosition, this.save(new CompoundNBT()), true));
this.notifyNeighbors();
}
private void emitScenarioStepPlay(String soundId) {
SoundSettings stepSettings = SoundSettings.sanitizedCopy(this.settings);
stepSettings.soundId = soundId;
this.playing = true;
SoundDebug.log(SoundDebug.Level.L1, "TRIGGER", this.debugPosId(), "scenario step play sourceId=sound_player:{} stepSoundId={} nextDelay={}", this.worldPosition.asLong(), soundId, this.scenarioWaitTicks);
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(() -> this.level.getChunkAt(this.worldPosition)), (Object)new S2CPlaySoundPacket("sound_player:" + this.worldPosition.asLong(), this.worldPosition, stepSettings));
this.notifyNeighbors();
}
public int getScenarioStepIndex() {
return this.scenarioStepIndex;
}
private void notifyNeighbors() {
if (this.level != null && !this.level.isClientSide) {
this.level.updateNeighborsAt(this.worldPosition, this.getBlockState().getBlock());
}
}
private boolean isSourceRuntimeActive() {
return this.playing || this.pendingStartTicks >= 0 || this.scenarioRunning;
}
private String debugPosId() {
return this.worldPosition.getX() + "," + this.worldPosition.getY() + "," + this.worldPosition.getZ();
}
private ZoneShape parseZoneShape(String raw) {
try {
return ZoneShape.valueOf(raw);
}
catch (Exception ignored) {
return ZoneShape.SPHERE;
}
}
private ZoneIntersectionPolicy parseZonePolicy(String raw) {
try {
return ZoneIntersectionPolicy.valueOf(raw);
}
catch (Exception ignored) {
return ZoneIntersectionPolicy.HIGHEST_PRIORITY;
}
}
private float clampFloat(float value, float min, float max) {
return Math.max(min, Math.min(max, value));
}
private double clampDouble(double value, double min, double max) {
return Math.max(min, Math.min(max, value));
}
}