Added HUD and changed time parsing
This commit is contained in:
parent
1da7485578
commit
a29b564805
11 changed files with 369 additions and 208 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
48
src/main/java/com/github/hhhzzzsss/songplayer/Util.java
Normal file
48
src/main/java/com/github/hhhzzzsss/songplayer/Util.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
"client": [
|
||||
"ClientPlayerEntityMixin",
|
||||
"ClientPlayNetworkHandlerMixin",
|
||||
"InGameHudMixin",
|
||||
"MinecraftClientMixin"
|
||||
],
|
||||
"injectors": {
|
||||
|
|
Loading…
Reference in a new issue