Added HUD and changed time parsing

This commit is contained in:
Harry Zhou 2022-06-27 23:03:28 -05:00
parent 1da7485578
commit a29b564805
11 changed files with 369 additions and 208 deletions

View file

@ -1,9 +1,10 @@
package com.github.hhhzzzsss.songplayer;
import com.github.hhhzzzsss.songplayer.noteblocks.SongHandler;
import com.github.hhhzzzsss.songplayer.playing.SongHandler;
import com.github.hhhzzzsss.songplayer.song.Song;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -175,20 +176,15 @@ public class CommandProcessor {
}
if (args.length() > 0) {
Pattern timestamp_pattern = Pattern.compile("(\\d+):(\\d+)");
Matcher timestamp_matcher = timestamp_pattern.matcher(args);
if (timestamp_matcher.matches()) {
String minutes = timestamp_matcher.group(1);
String seconds = timestamp_matcher.group(2);
SongHandler.getInstance().currentSong.setTime(Integer.parseInt(minutes)*60*1000 + Integer.parseInt(seconds)*1000);
SongPlayer.addChatMessage("§6Set song time to §3" + minutes + ":" + seconds);
return true;
}
else {
try {
long time = Util.parseTime(args);
SongHandler.getInstance().currentSong.setTime(time);
SongPlayer.addChatMessage("§6Set song time to §3" + Util.formatTime(time));
return true;
} catch (IOException e) {
SongPlayer.addChatMessage("§cNot a valid time stamp");
return true;
}
return false;
}
}
else {
return false;
@ -239,14 +235,10 @@ public class CommandProcessor {
return true;
}
Song currentSong = SongHandler.getInstance().currentSong;
long currentTime = Math.min(currentSong.time, currentSong.length);
long totalTime = currentSong.length;
if (args.length() == 0) {
int currTime = (int) (currentSong.time/1000);
int totTime = (int) (currentSong.length/1000);
int currTimeSeconds = currTime % 60;
int totTimeSeconds = totTime % 60;
int currTimeMinutes = currTime / 60;
int totTimeMinutes = totTime / 60;
SongPlayer.addChatMessage(String.format("§6Currently playing %s §3(%d:%02d/%d:%02d)", currentSong.name, currTimeMinutes, currTimeSeconds, totTimeMinutes, totTimeSeconds));
SongPlayer.addChatMessage(String.format("§6Currently playing %s §3(%s/%s)", Util.formatTime(currentTime), Util.formatTime(totalTime)));
return true;
}
else {

View file

@ -1,7 +1,7 @@
package com.github.hhhzzzsss.songplayer;
import com.github.hhhzzzsss.songplayer.noteblocks.SongHandler;
import com.github.hhhzzzsss.songplayer.noteblocks.Stage;
import com.github.hhhzzzsss.songplayer.playing.SongHandler;
import com.github.hhhzzzsss.songplayer.playing.Stage;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;

View file

@ -2,9 +2,6 @@ package com.github.hhhzzzsss.songplayer;
import java.io.File;
import com.github.hhhzzzsss.songplayer.noteblocks.Stage;
import com.github.hhhzzzsss.songplayer.song.Song;
import net.fabricmc.api.ModInitializer;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;

View file

@ -0,0 +1,48 @@
package com.github.hhhzzzsss.songplayer;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Util {
public static String formatTime(long milliseconds) {
long temp = Math.abs(milliseconds);
temp /= 1000;
long seconds = temp % 60;
temp /= 60;
long minutes = temp % 60;
temp /= 60;
long hours = temp;
StringBuilder sb = new StringBuilder();
if (milliseconds < 0) {
sb.append("-");
}
if (hours > 0) {
sb.append(String.format("%d:", hours));
sb.append(String.format("%02d:", minutes));
} else {
sb.append(String.format("%d:", minutes));
}
sb.append(String.format("%02d", seconds));
return sb.toString();
}
public static Pattern timePattern = Pattern.compile("(?:(\\d+)?:)(\\d+):(\\d+)");
public static long parseTime(String timeStr) throws IOException {
Matcher matcher = timePattern.matcher(timeStr);
if (matcher.matches()) {
long time = 0;
String hourString = matcher.group(1);
String minuteString = matcher.group(2);
String secondString = matcher.group(3);
if (hourString != null) {
time += Integer.parseInt(hourString) * 60 * 60 * 1000;
}
time += Integer.parseInt(minuteString) * 60 * 1000;
time += Double.parseDouble(secondString) * 1000.0;
return time;
} else {
throw new IOException("Invalid time pattern");
}
}
}

View file

@ -1,7 +1,7 @@
package com.github.hhhzzzsss.songplayer.mixin;
import com.github.hhhzzzsss.songplayer.noteblocks.SongHandler;
import com.github.hhhzzzsss.songplayer.noteblocks.Stage;
import com.github.hhhzzzsss.songplayer.playing.SongHandler;
import com.github.hhhzzzsss.songplayer.playing.Stage;
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -15,7 +15,6 @@ import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
@Mixin(ClientPlayNetworkHandler.class)

View file

@ -0,0 +1,33 @@
package com.github.hhhzzzsss.songplayer.mixin;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import com.github.hhhzzzsss.songplayer.playing.ProgressDisplay;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(InGameHud.class)
public class InGameHudMixin {
@Shadow
private int scaledWidth;
@Shadow
private int scaledHeight;
@Shadow
private int heldItemTooltipFade;
@Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;F)V",
at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;enableBlend()V", ordinal = 4))
private void onRender(MatrixStack matrixStack, float tickDelta, CallbackInfo ci) {
if (SongPlayer.MC.options.debugEnabled) {
return;
}
ProgressDisplay.getInstance().onRenderHUD(matrixStack, scaledWidth, scaledHeight, heldItemTooltipFade);
}
}

View file

@ -1,6 +1,7 @@
package com.github.hhhzzzsss.songplayer.mixin;
import com.github.hhhzzzsss.songplayer.noteblocks.SongHandler;
import com.github.hhhzzzsss.songplayer.playing.SongHandler;
import com.github.hhhzzzsss.songplayer.playing.ProgressDisplay;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -9,9 +10,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult.Type;
import net.minecraft.util.math.BlockPos;
@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {
@ -23,4 +21,9 @@ public class MinecraftClientMixin {
SongHandler.getInstance().onNotIngame();
}
}
@Inject(at = @At("HEAD"), method = "tick()V")
public void onTick(CallbackInfo ci) {
ProgressDisplay.getInstance().onTick();
}
}

View file

@ -0,0 +1,61 @@
package com.github.hhhzzzsss.songplayer.playing;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import java.util.Objects;
public class ProgressDisplay {
private static ProgressDisplay instance = null;
public static ProgressDisplay getInstance() {
if (instance == null) {
instance = new ProgressDisplay();
}
return instance;
}
private ProgressDisplay() {}
public MutableText displayText = Text.empty();
public int fade = 0;
public void setText(MutableText text) {
displayText = text;
fade = 100;
}
public void onRenderHUD(MatrixStack matrixStack, int scaledWidth, int scaledHeight, int heldItemTooltipFade) {
if (fade <= 0) {
return;
}
int textWidth = SongPlayer.MC.textRenderer.getWidth(displayText);
int textX = (scaledWidth - textWidth) / 2;
int textY = scaledHeight - 59;
if (!SongPlayer.MC.interactionManager.hasStatusBars()) {
textY += 14;
}
if (heldItemTooltipFade > 0) {
textY -= 12;
}
int opacity = (int)((float)this.fade * 256.0F / 10.0F);
if (opacity > 255) {
opacity = 255;
}
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
Objects.requireNonNull(SongPlayer.MC.textRenderer);
SongPlayer.MC.textRenderer.drawWithShadow(matrixStack, displayText, (float)textX, (float)textY, 16777215 + (opacity << 24));
RenderSystem.disableBlend();
}
public void onTick() {
if (fade > 0) {
fade--;
}
}
}

View file

@ -1,18 +1,17 @@
package com.github.hhhzzzsss.songplayer.noteblocks;
package com.github.hhhzzzsss.songplayer.playing;
import com.github.hhhzzzsss.songplayer.FakePlayerEntity;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import com.github.hhhzzzsss.songplayer.song.Instrument;
import com.github.hhhzzzsss.songplayer.song.Note;
import com.github.hhhzzzsss.songplayer.song.Song;
import com.github.hhhzzzsss.songplayer.song.SongLoaderThread;
import com.github.hhhzzzsss.songplayer.Util;
import com.github.hhhzzzsss.songplayer.song.*;
import net.minecraft.block.Block;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
@ -31,6 +30,7 @@ public class SongHandler {
}
return instance;
}
private SongHandler() {}
public SongLoaderThread loaderThread = null;
public LinkedList<Song> songQueue = new LinkedList<>();
@ -124,6 +124,7 @@ public class SongHandler {
private int buildEndDelay = 0;
private int buildCooldown = 0;
private void handleBuilding() {
setBuildProgressDisplay();
if (buildStartDelay > 0) {
buildStartDelay--;
return;
@ -133,7 +134,6 @@ public class SongHandler {
return;
}
ClientWorld world = SongPlayer.MC.world;
ClientPlayerEntity player = SongPlayer.MC.player;
if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.CREATIVE) {
return;
}
@ -177,9 +177,19 @@ public class SongHandler {
return;
}
}
private void setBuildProgressDisplay() {
MutableText text = Text.empty()
.append(Text.literal("Building noteblocks | " ).formatted(Formatting.GOLD))
.append(Text.literal((stage.totalMissingNotes - stage.missingNotes.size()) + "/" + stage.totalMissingNotes).formatted(Formatting.DARK_AQUA));
ProgressDisplay.getInstance().setText(text);
}
// Runs every frame
private void handlePlaying(boolean tick) {
if (tick) {
setPlayProgressDisplay();
}
if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.SURVIVAL) {
currentSong.pause();
return;
@ -217,6 +227,20 @@ public class SongHandler {
}
}
public void setPlayProgressDisplay() {
long currentTime = Math.min(currentSong.time, currentSong.length);
long totalTime = currentSong.length;
MutableText text = Text.empty()
.append(Text.literal("Now playing " ).formatted(Formatting.GOLD))
.append(Text.literal(currentSong.name).formatted(Formatting.BLUE))
.append(Text.literal(" | " ).formatted(Formatting.GOLD))
.append(Text.literal(String.format("%s/%s", Util.formatTime(currentTime), Util.formatTime(totalTime))).formatted(Formatting.DARK_AQUA));
if (currentSong.looping) {
text.append(Text.literal(" | Looping enabled" ).formatted(Formatting.GOLD));
}
ProgressDisplay.getInstance().setText(text);
}
public void cleanup() {
currentSong = null;
songQueue.clear();

View file

@ -1,167 +1,170 @@
package com.github.hhhzzzsss.songplayer.noteblocks;
import java.util.*;
import java.util.stream.Collectors;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import com.github.hhhzzzsss.songplayer.song.Song;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class Stage {
private final ClientPlayerEntity player = SongPlayer.MC.player;
public BlockPos position;
// public BlockPos[] tunedNoteblocks = new BlockPos[400];
public HashMap<Integer, BlockPos> noteblockPositions = new HashMap<>();
public boolean rebuild = false;
public LinkedList<BlockPos> requiredBreaks = new LinkedList<>();
public TreeSet<Integer> missingNotes = new TreeSet<>();
public Stage() {
position = player.getBlockPos();
}
public void movePlayerToStagePosition() {
player.getAbilities().allowFlying = true;
player.getAbilities().flying = true;
player.refreshPositionAndAngles(position.getX() + 0.5, position.getY() + 0.0, position.getZ() + 0.5, player.getYaw(), player.getPitch());
player.setVelocity(Vec3d.ZERO);
}
public void checkBuildStatus(Song song) {
noteblockPositions.clear();
missingNotes.clear();
// Add all required notes to missingNotes
for (int i=0; i<400; i++) {
if (song.requiredNotes[i]) {
missingNotes.add(i);
}
}
ArrayList<BlockPos> noteblockLocations = new ArrayList<>();
ArrayList<BlockPos> breakLocations = new ArrayList<>();
for (int dx = -4; dx <= 4; dx++) {
for (int dz = -4; dz <= 4; dz++) {
if (Math.abs(dx) == 4 && Math.abs(dz) == 4) {
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() + 0, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 1, position.getZ() + dz));
} else {
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() - 1, position.getZ() + dz));
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() + 2, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 0, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 1, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 3, position.getZ() + dz));
}
}
}
// Sorting noteblock and break locations
noteblockLocations.sort((a, b) -> {
// First sort by y
if (a.getY() < b.getY()) {
return -1;
} else if (a.getY() > b.getY()) {
return 1;
}
// Then sort by horizontal distance
int a_dx = a.getX() - position.getX();
int a_dz = a.getZ() - position.getZ();
int b_dx = b.getX() - position.getX();
int b_dz = b.getZ() - position.getZ();
int a_dist = a_dx*a_dx + a_dz*a_dz;
int b_dist = b_dx*b_dx + b_dz*b_dz;
if (a_dist < b_dist) {
return -1;
} else if (a_dist > b_dist) {
return 1;
}
// Finally sort by angle
double a_angle = Math.atan2(a_dz, a_dx);
double b_angle = Math.atan2(b_dz, b_dx);
if (a_angle < b_angle) {
return -1;
} else if (a_angle > b_angle) {
return 1;
} else {
return 0;
}
});
requiredBreaks = breakLocations
.stream()
.filter((bp) -> Block.getRawIdFromState(SongPlayer.MC.world.getBlockState(bp)) != 0)
.sorted((a, b) -> {
// First sort by y
if (a.getY() < b.getY()) {
return -1;
} else if (a.getY() > b.getY()) {
return 1;
}
// Then sort by horizontal distance
int a_dx = a.getX() - position.getX();
int a_dz = a.getZ() - position.getZ();
int b_dx = b.getX() - position.getX();
int b_dz = b.getZ() - position.getZ();
int a_dist = a_dx*a_dx + a_dz*a_dz;
int b_dist = b_dx*b_dx + b_dz*b_dz;
if (a_dist < b_dist) {
return -1;
} else if (a_dist > b_dist) {
return 1;
}
// Finally sort by angle
double a_angle = Math.atan2(a_dz, a_dx);
double b_angle = Math.atan2(b_dz, b_dx);
if (a_angle < b_angle) {
return -1;
} else if (a_angle > b_angle) {
return 1;
} else {
return 0;
}
})
.collect(Collectors.toCollection(LinkedList::new));
// Remove already-existing notes from missingNotes, adding their positions to noteblockPositions, and create a list of unused noteblock locations
ArrayList<BlockPos> unusedNoteblockLocations = new ArrayList<>();
for (BlockPos nbPos : noteblockLocations) {
BlockState bs = SongPlayer.MC.world.getBlockState(nbPos);
int blockId = Block.getRawIdFromState(bs);
if (blockId >= SongPlayer.NOTEBLOCK_BASE_ID && blockId < SongPlayer.NOTEBLOCK_BASE_ID+800) {
int noteId = (blockId-SongPlayer.NOTEBLOCK_BASE_ID)/2;
if (missingNotes.contains(noteId)) {
// stage.tunedNoteblocks[noteId] = pos;
missingNotes.remove(noteId);
noteblockPositions.put(noteId, nbPos);
}
else {
unusedNoteblockLocations.add(nbPos);
}
}
else {
unusedNoteblockLocations.add(nbPos);
}
}
// Populate missing noteblocks into the unused noteblock locations
int idx = 0;
for (int noteId : missingNotes) {
if (idx >= unusedNoteblockLocations.size()) {
System.out.println("Too many noteblocks!");
break;
}
noteblockPositions.put(noteId, unusedNoteblockLocations.get(idx++));
}
}
public boolean nothingToBuild() {
return requiredBreaks.isEmpty() && missingNotes.isEmpty();
}
}
package com.github.hhhzzzsss.songplayer.playing;
import java.util.*;
import java.util.stream.Collectors;
import com.github.hhhzzzsss.songplayer.SongPlayer;
import com.github.hhhzzzsss.songplayer.song.Song;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class Stage {
private final ClientPlayerEntity player = SongPlayer.MC.player;
public BlockPos position;
// public BlockPos[] tunedNoteblocks = new BlockPos[400];
public HashMap<Integer, BlockPos> noteblockPositions = new HashMap<>();
public boolean rebuild = false;
public LinkedList<BlockPos> requiredBreaks = new LinkedList<>();
public TreeSet<Integer> missingNotes = new TreeSet<>();
public int totalMissingNotes = 0;
public Stage() {
position = player.getBlockPos();
}
public void movePlayerToStagePosition() {
player.getAbilities().allowFlying = true;
player.getAbilities().flying = true;
player.refreshPositionAndAngles(position.getX() + 0.5, position.getY() + 0.0, position.getZ() + 0.5, player.getYaw(), player.getPitch());
player.setVelocity(Vec3d.ZERO);
}
public void checkBuildStatus(Song song) {
noteblockPositions.clear();
missingNotes.clear();
// Add all required notes to missingNotes
for (int i=0; i<400; i++) {
if (song.requiredNotes[i]) {
missingNotes.add(i);
}
}
ArrayList<BlockPos> noteblockLocations = new ArrayList<>();
ArrayList<BlockPos> breakLocations = new ArrayList<>();
for (int dx = -4; dx <= 4; dx++) {
for (int dz = -4; dz <= 4; dz++) {
if (Math.abs(dx) == 4 && Math.abs(dz) == 4) {
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() + 0, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 1, position.getZ() + dz));
} else {
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() - 1, position.getZ() + dz));
noteblockLocations.add(new BlockPos(position.getX() + dx, position.getY() + 2, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 0, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 1, position.getZ() + dz));
breakLocations.add(new BlockPos(position.getX() + dx, position.getY() + 3, position.getZ() + dz));
}
}
}
// Sorting noteblock and break locations
noteblockLocations.sort((a, b) -> {
// First sort by y
if (a.getY() < b.getY()) {
return -1;
} else if (a.getY() > b.getY()) {
return 1;
}
// Then sort by horizontal distance
int a_dx = a.getX() - position.getX();
int a_dz = a.getZ() - position.getZ();
int b_dx = b.getX() - position.getX();
int b_dz = b.getZ() - position.getZ();
int a_dist = a_dx*a_dx + a_dz*a_dz;
int b_dist = b_dx*b_dx + b_dz*b_dz;
if (a_dist < b_dist) {
return -1;
} else if (a_dist > b_dist) {
return 1;
}
// Finally sort by angle
double a_angle = Math.atan2(a_dz, a_dx);
double b_angle = Math.atan2(b_dz, b_dx);
if (a_angle < b_angle) {
return -1;
} else if (a_angle > b_angle) {
return 1;
} else {
return 0;
}
});
requiredBreaks = breakLocations
.stream()
.filter((bp) -> Block.getRawIdFromState(SongPlayer.MC.world.getBlockState(bp)) != 0)
.sorted((a, b) -> {
// First sort by y
if (a.getY() < b.getY()) {
return -1;
} else if (a.getY() > b.getY()) {
return 1;
}
// Then sort by horizontal distance
int a_dx = a.getX() - position.getX();
int a_dz = a.getZ() - position.getZ();
int b_dx = b.getX() - position.getX();
int b_dz = b.getZ() - position.getZ();
int a_dist = a_dx*a_dx + a_dz*a_dz;
int b_dist = b_dx*b_dx + b_dz*b_dz;
if (a_dist < b_dist) {
return -1;
} else if (a_dist > b_dist) {
return 1;
}
// Finally sort by angle
double a_angle = Math.atan2(a_dz, a_dx);
double b_angle = Math.atan2(b_dz, b_dx);
if (a_angle < b_angle) {
return -1;
} else if (a_angle > b_angle) {
return 1;
} else {
return 0;
}
})
.collect(Collectors.toCollection(LinkedList::new));
// Remove already-existing notes from missingNotes, adding their positions to noteblockPositions, and create a list of unused noteblock locations
ArrayList<BlockPos> unusedNoteblockLocations = new ArrayList<>();
for (BlockPos nbPos : noteblockLocations) {
BlockState bs = SongPlayer.MC.world.getBlockState(nbPos);
int blockId = Block.getRawIdFromState(bs);
if (blockId >= SongPlayer.NOTEBLOCK_BASE_ID && blockId < SongPlayer.NOTEBLOCK_BASE_ID+800) {
int noteId = (blockId-SongPlayer.NOTEBLOCK_BASE_ID)/2;
if (missingNotes.contains(noteId)) {
// stage.tunedNoteblocks[noteId] = pos;
missingNotes.remove(noteId);
noteblockPositions.put(noteId, nbPos);
}
else {
unusedNoteblockLocations.add(nbPos);
}
}
else {
unusedNoteblockLocations.add(nbPos);
}
}
// Populate missing noteblocks into the unused noteblock locations
int idx = 0;
for (int noteId : missingNotes) {
if (idx >= unusedNoteblockLocations.size()) {
System.out.println("Too many noteblocks!");
break;
}
noteblockPositions.put(noteId, unusedNoteblockLocations.get(idx++));
}
// Set total missing notes
totalMissingNotes = missingNotes.size();
}
public boolean nothingToBuild() {
return requiredBreaks.isEmpty() && missingNotes.isEmpty();
}
}

View file

@ -8,6 +8,7 @@
"client": [
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin",
"InGameHudMixin",
"MinecraftClientMixin"
],
"injectors": {