Merge pull request #28 from EnderKill98/feature/various-improvements-and-1.21-support
Fix ranges, fix #25 and support 1.21
This commit is contained in:
commit
7bf1089199
@ -2,8 +2,8 @@
|
|||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx1G
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://modmuss50.me/fabric.html
|
# check these on https://modmuss50.me/fabric.html
|
||||||
minecraft_version=1.20.6
|
minecraft_version=1.21
|
||||||
yarn_mappings=1.20.6+build.1
|
yarn_mappings=1.21+build.2
|
||||||
loader_version=0.15.11
|
loader_version=0.15.11
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=1.5.0
|
mod_version=1.5.0
|
||||||
@ -11,4 +11,4 @@ maven_group=semmiedev
|
|||||||
archives_base_name=disc_jockey
|
archives_base_name=disc_jockey
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# check this on https://modmuss50.me/fabric.html
|
# check this on https://modmuss50.me/fabric.html
|
||||||
fabric_version=0.98.0+1.20.6
|
fabric_version=0.100.1+1.21
|
||||||
|
@ -12,6 +12,32 @@ public class Config implements ConfigData {
|
|||||||
@ConfigEntry.Gui.Tooltip(count = 2) public boolean disableAsyncPlayback;
|
@ConfigEntry.Gui.Tooltip(count = 2) public boolean disableAsyncPlayback;
|
||||||
@ConfigEntry.Gui.Tooltip(count = 2) public boolean omnidirectionalNoteBlockSounds = true;
|
@ConfigEntry.Gui.Tooltip(count = 2) public boolean omnidirectionalNoteBlockSounds = true;
|
||||||
|
|
||||||
|
public enum ExpectedServerVersion {
|
||||||
|
All,
|
||||||
|
v1_20_4_Or_Earlier,
|
||||||
|
v1_20_5_Or_Later;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if(this == All) {
|
||||||
|
return "All (universal)";
|
||||||
|
}else if(this == v1_20_4_Or_Earlier) {
|
||||||
|
return "≤1.20.4";
|
||||||
|
}else if (this == v1_20_5_Or_Later) {
|
||||||
|
return "≥1.20.5";
|
||||||
|
}else {
|
||||||
|
return super.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
|
||||||
|
@ConfigEntry.Gui.Tooltip(count = 4)
|
||||||
|
public ExpectedServerVersion expectedServerVersion = ExpectedServerVersion.All;
|
||||||
|
|
||||||
|
@ConfigEntry.Gui.Tooltip(count = 1)
|
||||||
|
public float delayPlaybackStartBySecs = 0.0f;
|
||||||
|
|
||||||
@ConfigEntry.Gui.Excluded
|
@ConfigEntry.Gui.Excluded
|
||||||
public ArrayList<String> favorites = new ArrayList<>();
|
public ArrayList<String> favorites = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,10 @@ import com.mojang.brigadier.arguments.FloatArgumentType;
|
|||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.block.enums.Instrument;
|
import net.minecraft.block.enums.NoteBlockInstrument;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import semmiedev.disc_jockey.gui.screen.DiscJockeyScreen;
|
import semmiedev.disc_jockey.gui.screen.DiscJockeyScreen;
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ public class DiscjockeyCommand {
|
|||||||
|
|
||||||
public static void register(CommandDispatcher<FabricClientCommandSource> commandDispatcher) {
|
public static void register(CommandDispatcher<FabricClientCommandSource> commandDispatcher) {
|
||||||
final ArrayList<String> instrumentNames = new ArrayList<>();
|
final ArrayList<String> instrumentNames = new ArrayList<>();
|
||||||
for (Instrument instrument : Instrument.values()) {
|
for (NoteBlockInstrument instrument : NoteBlockInstrument.values()) {
|
||||||
instrumentNames.add(instrument.toString().toLowerCase());
|
instrumentNames.add(instrument.toString().toLowerCase());
|
||||||
}
|
}
|
||||||
final ArrayList<String> instrumentNamesAndAll = new ArrayList<>(instrumentNames);
|
final ArrayList<String> instrumentNamesAndAll = new ArrayList<>(instrumentNames);
|
||||||
@ -127,8 +126,8 @@ public class DiscjockeyCommand {
|
|||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
String originalInstrumentStr = StringArgumentType.getString(context, "originalInstrument");
|
String originalInstrumentStr = StringArgumentType.getString(context, "originalInstrument");
|
||||||
String newInstrumentStr = StringArgumentType.getString(context, "newInstrument");
|
String newInstrumentStr = StringArgumentType.getString(context, "newInstrument");
|
||||||
@Nullable Instrument originalInstrument = null, newInstrument = null;
|
@Nullable NoteBlockInstrument originalInstrument = null, newInstrument = null;
|
||||||
for(Instrument maybeInstrument : Instrument.values()) {
|
for(NoteBlockInstrument maybeInstrument : NoteBlockInstrument.values()) {
|
||||||
if(maybeInstrument.toString().equalsIgnoreCase(originalInstrumentStr)) {
|
if(maybeInstrument.toString().equalsIgnoreCase(originalInstrumentStr)) {
|
||||||
originalInstrument = maybeInstrument;
|
originalInstrument = maybeInstrument;
|
||||||
}
|
}
|
||||||
@ -152,7 +151,7 @@ public class DiscjockeyCommand {
|
|||||||
|
|
||||||
if(originalInstrument == null) {
|
if(originalInstrument == null) {
|
||||||
// All instruments
|
// All instruments
|
||||||
for(Instrument instrument : Instrument.values()) {
|
for(NoteBlockInstrument instrument : NoteBlockInstrument.values()) {
|
||||||
Main.SONG_PLAYER.instrumentMap.put(instrument, newInstrument);
|
Main.SONG_PLAYER.instrumentMap.put(instrument, newInstrument);
|
||||||
}
|
}
|
||||||
context.getSource().sendFeedback(Text.translatable(Main.MOD_ID + ".instrument_mapped_all", newInstrumentStr.toLowerCase()));
|
context.getSource().sendFeedback(Text.translatable(Main.MOD_ID + ".instrument_mapped_all", newInstrumentStr.toLowerCase()));
|
||||||
@ -171,8 +170,8 @@ public class DiscjockeyCommand {
|
|||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
String instrumentStr = StringArgumentType.getString(context, "instrument");
|
String instrumentStr = StringArgumentType.getString(context, "instrument");
|
||||||
|
|
||||||
Instrument instrument = null;
|
NoteBlockInstrument instrument = null;
|
||||||
for(Instrument maybeInstrument : Instrument.values()) {
|
for(NoteBlockInstrument maybeInstrument : NoteBlockInstrument.values()) {
|
||||||
if(maybeInstrument.toString().equalsIgnoreCase(instrumentStr)) {
|
if(maybeInstrument.toString().equalsIgnoreCase(instrumentStr)) {
|
||||||
instrument = maybeInstrument;
|
instrument = maybeInstrument;
|
||||||
break;
|
break;
|
||||||
@ -198,7 +197,7 @@ public class DiscjockeyCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder maps = new StringBuilder();
|
StringBuilder maps = new StringBuilder();
|
||||||
for(Map.Entry<Instrument, Instrument> entry : Main.SONG_PLAYER.instrumentMap.entrySet()) {
|
for(Map.Entry<NoteBlockInstrument, NoteBlockInstrument> entry : Main.SONG_PLAYER.instrumentMap.entrySet()) {
|
||||||
if(maps.length() > 0) {
|
if(maps.length() > 0) {
|
||||||
maps.append(", ");
|
maps.append(", ");
|
||||||
}
|
}
|
||||||
|
@ -2,52 +2,53 @@ package semmiedev.disc_jockey;
|
|||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.enums.Instrument;
|
import net.minecraft.block.enums.NoteBlockInstrument;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public record Note(Instrument instrument, byte note) {
|
public record Note(NoteBlockInstrument instrument, byte note) {
|
||||||
public static final HashMap<Instrument, Block> INSTRUMENT_BLOCKS = new HashMap<>();
|
public static final HashMap<NoteBlockInstrument, Block> INSTRUMENT_BLOCKS = new HashMap<>();
|
||||||
|
|
||||||
public static final byte LAYER_SHIFT = Short.SIZE;
|
public static final byte LAYER_SHIFT = Short.SIZE;
|
||||||
public static final byte INSTRUMENT_SHIFT = Short.SIZE * 2;
|
public static final byte INSTRUMENT_SHIFT = Short.SIZE * 2;
|
||||||
public static final byte NOTE_SHIFT = Short.SIZE * 2 + Byte.SIZE;
|
public static final byte NOTE_SHIFT = Short.SIZE * 2 + Byte.SIZE;
|
||||||
|
|
||||||
public static final Instrument[] INSTRUMENTS = new Instrument[]{
|
public static final NoteBlockInstrument[] INSTRUMENTS = new NoteBlockInstrument[]{
|
||||||
Instrument.HARP,
|
NoteBlockInstrument.HARP,
|
||||||
Instrument.BASS,
|
NoteBlockInstrument.BASS,
|
||||||
Instrument.BASEDRUM,
|
NoteBlockInstrument.BASEDRUM,
|
||||||
Instrument.SNARE,
|
NoteBlockInstrument.SNARE,
|
||||||
Instrument.HAT,
|
NoteBlockInstrument.HAT,
|
||||||
Instrument.GUITAR,
|
NoteBlockInstrument.GUITAR,
|
||||||
Instrument.FLUTE,
|
NoteBlockInstrument.FLUTE,
|
||||||
Instrument.BELL,
|
NoteBlockInstrument.BELL,
|
||||||
Instrument.CHIME,
|
NoteBlockInstrument.CHIME,
|
||||||
Instrument.XYLOPHONE,
|
NoteBlockInstrument.XYLOPHONE,
|
||||||
Instrument.IRON_XYLOPHONE,
|
NoteBlockInstrument.IRON_XYLOPHONE,
|
||||||
Instrument.COW_BELL,
|
NoteBlockInstrument.COW_BELL,
|
||||||
Instrument.DIDGERIDOO,
|
NoteBlockInstrument.DIDGERIDOO,
|
||||||
Instrument.BIT,
|
NoteBlockInstrument.BIT,
|
||||||
Instrument.BANJO,
|
NoteBlockInstrument.BANJO,
|
||||||
Instrument.PLING
|
NoteBlockInstrument.PLING
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.HARP, Blocks.AIR);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.HARP, Blocks.AIR);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.BASEDRUM, Blocks.STONE);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.BASEDRUM, Blocks.STONE);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.SNARE, Blocks.SAND);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.SNARE, Blocks.SAND);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.HAT, Blocks.GLASS);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.HAT, Blocks.GLASS);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.BASS, Blocks.OAK_PLANKS);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.BASS, Blocks.OAK_PLANKS);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.FLUTE, Blocks.CLAY);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.FLUTE, Blocks.CLAY);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.BELL, Blocks.GOLD_BLOCK);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.BELL, Blocks.GOLD_BLOCK);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.GUITAR, Blocks.WHITE_WOOL);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.GUITAR, Blocks.WHITE_WOOL);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.CHIME, Blocks.PACKED_ICE);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.CHIME, Blocks.PACKED_ICE);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.XYLOPHONE, Blocks.BONE_BLOCK);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.XYLOPHONE, Blocks.BONE_BLOCK);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.IRON_XYLOPHONE, Blocks.IRON_BLOCK);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.IRON_XYLOPHONE, Blocks.IRON_BLOCK);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.COW_BELL, Blocks.SOUL_SAND);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.COW_BELL, Blocks.SOUL_SAND);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.DIDGERIDOO, Blocks.PUMPKIN);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.DIDGERIDOO, Blocks.PUMPKIN);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.BIT, Blocks.EMERALD_BLOCK);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.BIT, Blocks.EMERALD_BLOCK);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.BANJO, Blocks.HAY_BLOCK);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.BANJO, Blocks.HAY_BLOCK);
|
||||||
INSTRUMENT_BLOCKS.put(Instrument.PLING, Blocks.GLOWSTONE);
|
INSTRUMENT_BLOCKS.put(NoteBlockInstrument.PLING, Blocks.GLOWSTONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.enums.Instrument;
|
import net.minecraft.block.enums.NoteBlockInstrument;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.hud.ChatHud;
|
import net.minecraft.client.gui.hud.ChatHud;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
@ -18,11 +18,9 @@ import net.minecraft.util.Formatting;
|
|||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Pair;
|
import net.minecraft.util.Pair;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.GameMode;
|
import net.minecraft.world.GameMode;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -37,7 +35,7 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
|
|
||||||
private int index;
|
private int index;
|
||||||
private double tick; // Aka song position
|
private double tick; // Aka song position
|
||||||
private HashMap<Instrument, HashMap<Byte, BlockPos>> noteBlocks = null;
|
private HashMap<NoteBlockInstrument, HashMap<Byte, BlockPos>> noteBlocks = null;
|
||||||
public boolean tuned;
|
public boolean tuned;
|
||||||
private long lastPlaybackTickAt = -1L;
|
private long lastPlaybackTickAt = -1L;
|
||||||
|
|
||||||
@ -65,12 +63,13 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
private HashMap<BlockPos, Pair<Integer, Long>> notePredictions = new HashMap<>();
|
private HashMap<BlockPos, Pair<Integer, Long>> notePredictions = new HashMap<>();
|
||||||
public boolean didSongReachEnd = false;
|
public boolean didSongReachEnd = false;
|
||||||
public boolean loopSong = false;
|
public boolean loopSong = false;
|
||||||
|
private long pausePlaybackUntil = -1L; // Set after tuning, if configured
|
||||||
|
|
||||||
public SongPlayer() {
|
public SongPlayer() {
|
||||||
Main.TICK_LISTENERS.add(this);
|
Main.TICK_LISTENERS.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull HashMap<Instrument, @Nullable Instrument> instrumentMap = new HashMap<>(); // Toy
|
public @NotNull HashMap<NoteBlockInstrument, @Nullable NoteBlockInstrument> instrumentMap = new HashMap<>(); // Toy
|
||||||
public synchronized void startPlaybackThread() {
|
public synchronized void startPlaybackThread() {
|
||||||
if(Main.config.disableAsyncPlayback) {
|
if(Main.config.disableAsyncPlayback) {
|
||||||
playbackThread = null;
|
playbackThread = null;
|
||||||
@ -155,6 +154,7 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
last100MsSpanEstimatedPackets = 0;
|
last100MsSpanEstimatedPackets = 0;
|
||||||
}
|
}
|
||||||
if(noteBlocks != null && tuned) {
|
if(noteBlocks != null && tuned) {
|
||||||
|
if(pausePlaybackUntil != -1L && System.currentTimeMillis() <= pausePlaybackUntil) return;
|
||||||
while (running) {
|
while (running) {
|
||||||
MinecraftClient client = MinecraftClient.getInstance();
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
GameMode gameMode = client.interactionManager == null ? null : client.interactionManager.getCurrentGameMode();
|
GameMode gameMode = client.interactionManager == null ? null : client.interactionManager.getCurrentGameMode();
|
||||||
@ -254,16 +254,32 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
ClientPlayerEntity player = client.player;
|
ClientPlayerEntity player = client.player;
|
||||||
|
|
||||||
// Create list of available noteblock positions per used instrument
|
// Create list of available noteblock positions per used instrument
|
||||||
HashMap<Instrument, ArrayList<BlockPos>> noteblocksForInstrument = new HashMap<>();
|
HashMap<NoteBlockInstrument, ArrayList<BlockPos>> noteblocksForInstrument = new HashMap<>();
|
||||||
for(Instrument instrument : Instrument.values())
|
for(NoteBlockInstrument instrument : NoteBlockInstrument.values())
|
||||||
noteblocksForInstrument.put(instrument, new ArrayList<>());
|
noteblocksForInstrument.put(instrument, new ArrayList<>());
|
||||||
final Vec3d playerPos = player.getEyePos();
|
final Vec3d playerEyePos = player.getEyePos();
|
||||||
final int[] orderedOffsets = new int[] { 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7 };
|
|
||||||
for(Instrument instrument : noteblocksForInstrument.keySet().toArray(new Instrument[0])) {
|
final int maxOffset; // Rough estimates, of which blocks could be in reach
|
||||||
|
if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.v1_20_4_Or_Earlier) {
|
||||||
|
maxOffset = 7;
|
||||||
|
}else if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.v1_20_5_Or_Later) {
|
||||||
|
maxOffset = (int) Math.ceil(player.getBlockInteractionRange() + 1.0 + 1.0);
|
||||||
|
}else if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.All) {
|
||||||
|
maxOffset = Math.min(7, (int) Math.ceil(player.getBlockInteractionRange() + 1.0 + 1.0));
|
||||||
|
}else {
|
||||||
|
throw new NotImplementedException("ExpectedServerVersion Value not implemented: " + Main.config.expectedServerVersion.name());
|
||||||
|
}
|
||||||
|
final ArrayList<Integer> orderedOffsets = new ArrayList<>();
|
||||||
|
for(int offset = 0; offset <= maxOffset; offset++) {
|
||||||
|
orderedOffsets.add(offset);
|
||||||
|
if(offset != 0) orderedOffsets.add(offset * -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(NoteBlockInstrument instrument : noteblocksForInstrument.keySet().toArray(new NoteBlockInstrument[0])) {
|
||||||
for (int y : orderedOffsets) {
|
for (int y : orderedOffsets) {
|
||||||
for (int x : orderedOffsets) {
|
for (int x : orderedOffsets) {
|
||||||
for (int z : orderedOffsets) {
|
for (int z : orderedOffsets) {
|
||||||
Vec3d vec3d = playerPos.add(x, y, z);
|
Vec3d vec3d = playerEyePos.add(x, y, z);
|
||||||
BlockPos blockPos = new BlockPos(MathHelper.floor(vec3d.x), MathHelper.floor(vec3d.y), MathHelper.floor(vec3d.z));
|
BlockPos blockPos = new BlockPos(MathHelper.floor(vec3d.x), MathHelper.floor(vec3d.y), MathHelper.floor(vec3d.z));
|
||||||
if (!canInteractWith(player, blockPos))
|
if (!canInteractWith(player, blockPos))
|
||||||
continue;
|
continue;
|
||||||
@ -280,9 +296,9 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
|
|
||||||
// Remap instruments for funzies
|
// Remap instruments for funzies
|
||||||
if(!instrumentMap.isEmpty()) {
|
if(!instrumentMap.isEmpty()) {
|
||||||
HashMap<Instrument, ArrayList<BlockPos>> newNoteblocksForInstrument = new HashMap<>();
|
HashMap<NoteBlockInstrument, ArrayList<BlockPos>> newNoteblocksForInstrument = new HashMap<>();
|
||||||
for(Instrument orig : noteblocksForInstrument.keySet()) {
|
for(NoteBlockInstrument orig : noteblocksForInstrument.keySet()) {
|
||||||
Instrument mappedInstrument = instrumentMap.getOrDefault(orig, orig);
|
NoteBlockInstrument mappedInstrument = instrumentMap.getOrDefault(orig, orig);
|
||||||
if(mappedInstrument == null) {
|
if(mappedInstrument == null) {
|
||||||
// Instrument got likely mapped to "nothing"
|
// Instrument got likely mapped to "nothing"
|
||||||
newNoteblocksForInstrument.put(orig, null);
|
newNoteblocksForInstrument.put(orig, null);
|
||||||
@ -332,7 +348,7 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
|
|
||||||
HashMap<Block, Integer> missing = new HashMap<>();
|
HashMap<Block, Integer> missing = new HashMap<>();
|
||||||
for (Note note : missingNotes) {
|
for (Note note : missingNotes) {
|
||||||
Instrument mappedInstrument = instrumentMap.getOrDefault(note.instrument(), note.instrument());
|
NoteBlockInstrument mappedInstrument = instrumentMap.getOrDefault(note.instrument(), note.instrument());
|
||||||
if(mappedInstrument == null) continue; // Ignore if mapped to nothing
|
if(mappedInstrument == null) continue; // Ignore if mapped to nothing
|
||||||
Block block = Note.INSTRUMENT_BLOCKS.get(mappedInstrument);
|
Block block = Note.INSTRUMENT_BLOCKS.get(mappedInstrument);
|
||||||
Integer got = missing.get(block);
|
Integer got = missing.get(block);
|
||||||
@ -403,7 +419,9 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
// Wait roundrip + 100ms before considering tuned after changing notes (in case the server rejects an interact)
|
// Wait roundrip + 100ms before considering tuned after changing notes (in case the server rejects an interact)
|
||||||
if(lastInteractAt == -1 || System.currentTimeMillis() - lastInteractAt >= ping * 2 + 100) {
|
if(lastInteractAt == -1 || System.currentTimeMillis() - lastInteractAt >= ping * 2 + 100) {
|
||||||
tuned = true;
|
tuned = true;
|
||||||
|
pausePlaybackUntil = System.currentTimeMillis() + (long) (Math.abs(Main.config.delayPlaybackStartBySecs) * 1000);
|
||||||
tuneInitialUntunedBlocks = -1;
|
tuneInitialUntunedBlocks = -1;
|
||||||
|
// Tuning finished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,13 +485,28 @@ public class SongPlayer implements ClientTickEvents.StartWorldTick {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<Byte, BlockPos> getNotes(Instrument instrument) {
|
private HashMap<Byte, BlockPos> getNotes(NoteBlockInstrument instrument) {
|
||||||
return noteBlocks.computeIfAbsent(instrument, k -> new HashMap<>());
|
return noteBlocks.computeIfAbsent(instrument, k -> new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The server limits interacts to 6 Blocks from Player Eye to Block Center
|
// Before 1.20.5, the server limits interacts to 6 Blocks from Player Eye to Block Center
|
||||||
|
// With 1.20.5 and later, the server does a more complex check, to the closest point of a full block hitbox
|
||||||
|
// (max distance is BlockInteractRange + 1.0).
|
||||||
private boolean canInteractWith(ClientPlayerEntity player, BlockPos blockPos) {
|
private boolean canInteractWith(ClientPlayerEntity player, BlockPos blockPos) {
|
||||||
return player.getEyePos().squaredDistanceTo(new Vec3d(blockPos.getX() + 0.5, blockPos.getY() + 0.5, blockPos.getZ() + 0.5)) <= 6.0*6.0;
|
final Vec3d eyePos = player.getEyePos();
|
||||||
|
if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.v1_20_4_Or_Earlier) {
|
||||||
|
return eyePos.squaredDistanceTo(blockPos.toCenterPos()) <= 6.0 * 6.0;
|
||||||
|
}else if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.v1_20_5_Or_Later) {
|
||||||
|
double blockInteractRange = player.getBlockInteractionRange() + 1.0;
|
||||||
|
return new Box(blockPos).squaredMagnitude(eyePos) < blockInteractRange * blockInteractRange;
|
||||||
|
}else if(Main.config.expectedServerVersion == Config.ExpectedServerVersion.All) {
|
||||||
|
// Require both checks to succeed (aka use worst distance)
|
||||||
|
double blockInteractRange = player.getBlockInteractionRange() + 1.0;
|
||||||
|
return eyePos.squaredDistanceTo(blockPos.toCenterPos()) <= 6.0 * 6.0
|
||||||
|
&& new Box(blockPos).squaredMagnitude(eyePos) < blockInteractRange * blockInteractRange;
|
||||||
|
}else {
|
||||||
|
throw new NotImplementedException("ExpectedServerVersion Value not implemented: " + Main.config.expectedServerVersion.name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getSongElapsedSeconds() {
|
public double getSongElapsedSeconds() {
|
||||||
|
@ -41,7 +41,7 @@ public class SongListWidget extends EntryListWidget<SongListWidget.SongEntry> {
|
|||||||
|
|
||||||
// TODO: 6/2/2022 Add a delete icon
|
// TODO: 6/2/2022 Add a delete icon
|
||||||
public static class SongEntry extends Entry<SongEntry> {
|
public static class SongEntry extends Entry<SongEntry> {
|
||||||
private static final Identifier ICONS = new Identifier(Main.MOD_ID, "textures/gui/icons.png");
|
private static final Identifier ICONS = Identifier.of(Main.MOD_ID, "textures/gui/icons.png");
|
||||||
|
|
||||||
public final int index;
|
public final int index;
|
||||||
public final Song song;
|
public final Song song;
|
||||||
|
@ -4,6 +4,7 @@ import net.minecraft.block.Blocks;
|
|||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.font.TextRenderer;
|
import net.minecraft.client.font.TextRenderer;
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.render.RenderTickCounter;
|
||||||
import net.minecraft.client.render.item.ItemRenderer;
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.ColorHelper;
|
import net.minecraft.util.math.ColorHelper;
|
||||||
@ -15,7 +16,7 @@ public class BlocksOverlay {
|
|||||||
|
|
||||||
private static final ItemStack NOTE_BLOCK = Blocks.NOTE_BLOCK.asItem().getDefaultStack();
|
private static final ItemStack NOTE_BLOCK = Blocks.NOTE_BLOCK.asItem().getDefaultStack();
|
||||||
|
|
||||||
public static void render(DrawContext context, float tickDelta) {
|
public static void render(DrawContext context, RenderTickCounter tickCounter) {
|
||||||
if (itemStacks != null) {
|
if (itemStacks != null) {
|
||||||
context.fill(2, 2, 62, (itemStacks.length + 1) * 20 + 7, ColorHelper.Argb.getArgb(255, 22, 22, 27));
|
context.fill(2, 2, 62, (itemStacks.length + 1) * 20 + 7, ColorHelper.Argb.getArgb(255, 22, 22, 27));
|
||||||
context.fill(4, 4, 60, (itemStacks.length + 1) * 20 + 5, ColorHelper.Argb.getArgb(255, 42, 42, 47));
|
context.fill(4, 4, 60, (itemStacks.length + 1) * 20 + 5, ColorHelper.Argb.getArgb(255, 42, 42, 47));
|
||||||
|
@ -44,5 +44,12 @@
|
|||||||
"text.autoconfig.disc_jockey.option.disableAsyncPlayback.@Tooltip[1]": "This can lead to performance loss, especially when you client has low or inconsistent fps but can fix issues when playback does not happen at all.",
|
"text.autoconfig.disc_jockey.option.disableAsyncPlayback.@Tooltip[1]": "This can lead to performance loss, especially when you client has low or inconsistent fps but can fix issues when playback does not happen at all.",
|
||||||
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds": "Omnidirectional Note Block Sounds (clientside)",
|
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds": "Omnidirectional Note Block Sounds (clientside)",
|
||||||
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[0]": "Makes all note block sounds when playing a song omnidirectional, creating a more pleasing listening experience",
|
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[0]": "Makes all note block sounds when playing a song omnidirectional, creating a more pleasing listening experience",
|
||||||
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[1]": "If you don't know what that means, I recommend you just try it and hear the difference"
|
"text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[1]": "If you don't know what that means, I recommend you just try it and hear the difference",
|
||||||
|
"text.autoconfig.disc_jockey.option.expectedServerVersion": "Expected Server Version",
|
||||||
|
"text.autoconfig.disc_jockey.option.expectedServerVersion.@Tooltip[0]": "Select the server version, you expect this mod to be used on.",
|
||||||
|
"text.autoconfig.disc_jockey.option.expectedServerVersion.@Tooltip[1]": "This affects how reachable NoteBlocks are determined.",
|
||||||
|
"text.autoconfig.disc_jockey.option.expectedServerVersion.@Tooltip[2]": "Selecting the wrong version could cause you not to be able to play some distant note blocks which could break/worsen playback",
|
||||||
|
"text.autoconfig.disc_jockey.option.expectedServerVersion.@Tooltip[3]": "If you're unsure, or play on many different server versions and don't mind not reaching every possible note block, select \"All\"",
|
||||||
|
"text.autoconfig.disc_jockey.option.delayPlaybackStartBySecs": "Delay playback by (seconds)",
|
||||||
|
"text.autoconfig.disc_jockey.option.delayPlaybackStartBySecs.@Tooltip": "Delays playback for specified seconds, after tuning finished, if any (e.g. 0.5 for half a second delay)."
|
||||||
}
|
}
|
@ -27,7 +27,7 @@
|
|||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabric": "*",
|
"fabric": "*",
|
||||||
"minecraft": ">=1.20.5 <=1.20.6",
|
"minecraft": "~1.21",
|
||||||
"cloth-config": "*"
|
"cloth-config": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user