diff --git a/src/main/java/dev/adventurecraft/awakening/common/AC_GuiMusicSheet.java b/src/main/java/dev/adventurecraft/awakening/common/AC_GuiMusicSheet.java
index 306a4f21..fecea367 100644
--- a/src/main/java/dev/adventurecraft/awakening/common/AC_GuiMusicSheet.java
+++ b/src/main/java/dev/adventurecraft/awakening/common/AC_GuiMusicSheet.java
@@ -1,5 +1,7 @@
package dev.adventurecraft.awakening.common;
+import dev.adventurecraft.awakening.common.instruments.IInstrumentConfig;
+import dev.adventurecraft.awakening.common.instruments.Note;
import dev.adventurecraft.awakening.extension.client.gui.screen.ExScreen;
import dev.adventurecraft.awakening.extension.world.ExWorld;
import it.unimi.dsi.fastutil.ints.IntArrayList;
@@ -10,27 +12,32 @@
public class AC_GuiMusicSheet extends Screen {
- private String instrument;
- private IntArrayList notesPlayed;
+ private final IInstrumentConfig instrument;
+ private final IntArrayList notesPlayed;
private String notesPlayedString;
private int spaceTaken;
private AC_MusicScriptEntry songPlayed;
private long timeToFade;
- public AC_GuiMusicSheet(String instrument) {
+ public AC_GuiMusicSheet(IInstrumentConfig instrument) {
this.instrument = instrument;
this.notesPlayed = new IntArrayList();
this.notesPlayedString = "";
this.songPlayed = null;
}
- @Override
- public void tick() {
- }
-
- @Override
- public void initVanillaScreen() {
- }
+ public static final Note[] keyboardNotes = {
+ new Note('D', -1), // Keyboard 1
+ new Note('E', -1),
+ new Note('F', -1),
+ new Note('G', -1),
+ new Note('A', 0),
+ new Note('B', 0),
+ new Note('C', 0),
+ new Note('D', 0),
+ new Note('E', 0),
+ new Note('F', 0), // Keyboard 0
+ };
@Override
protected void keyPressed(char character, int key) {
@@ -65,7 +72,6 @@ protected void keyPressed(char character, int key) {
int totalSpaceTaken = this.spaceTaken + NOTE_SIZE;
-
if (totalSpaceTaken >= MAX_NOTE_SPACE) {
this.notesPlayed.clear();
this.notesPlayedString = "";
@@ -75,36 +81,17 @@ protected void keyPressed(char character, int key) {
this.spaceTaken += NOTE_SIZE;
this.notesPlayed.add(key);
- if (key == Keyboard.KEY_1) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'D', shiftDown, 0.5F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "1";
- } else if (key == Keyboard.KEY_2) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'E', false, 0.5F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "2";
- } else if (key == Keyboard.KEY_3) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'F', shiftDown, 0.5F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "3";
- } else if (key == Keyboard.KEY_4) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'G', shiftDown, 0.5F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "4";
- } else if (key == Keyboard.KEY_5) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'A', shiftDown, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "5";
- } else if (key == Keyboard.KEY_6) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'B', false, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "6";
- } else if (key == Keyboard.KEY_7) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'C', shiftDown, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "7";
- } else if (key == Keyboard.KEY_8) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'D', shiftDown, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "8";
- } else if (key == Keyboard.KEY_9) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'E', false, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "9";
- } else if (key == Keyboard.KEY_0) {
- MusicPlayer.playNoteFromEntity(this.client.world, this.client.player, this.instrument, 'F', shiftDown, 1.0F, 1.0F);
- this.notesPlayedString = this.notesPlayedString + "0";
+ Note noteToPlay = keyboardNotes[key - Keyboard.KEY_1];
+ this.notesPlayedString += Keyboard.getKeyName(key);
+
+
+ if (noteToPlay != null) {
+ int totalShiftValue = this.instrument.getTuning();
+ if (noteIsSharp)
+ totalShiftValue += 1;
+ noteToPlay = noteToPlay.withShiftedValue(totalShiftValue);
+
+ MusicPlayer.playNoteFromEntity(this.client.player, this.instrument, noteToPlay, 1F);
}
AC_MusicScriptEntry entry = ((ExWorld) this.client.world).getMusicScripts().executeMusic(this.notesPlayedString);
@@ -173,8 +160,8 @@ private void drawSharp(int x, int note) {
this.blit((this.width - 205) / 2 + 36 + x, this.height - 59 - 2 - 48 + 46 - (note - 2) * 4 - 5, 16, 64, 12, 17);
}
- public static void showUI(String var0) {
- Minecraft.instance.openScreen(new AC_GuiMusicSheet(var0));
+ public static void showUI(IInstrumentConfig instrumentConfig) {
+ Minecraft.instance.openScreen(new AC_GuiMusicSheet(instrumentConfig));
}
@Override
diff --git a/src/main/java/dev/adventurecraft/awakening/common/AC_ItemInstrument.java b/src/main/java/dev/adventurecraft/awakening/common/AC_ItemInstrument.java
index 3c4549d9..5f2193c3 100644
--- a/src/main/java/dev/adventurecraft/awakening/common/AC_ItemInstrument.java
+++ b/src/main/java/dev/adventurecraft/awakening/common/AC_ItemInstrument.java
@@ -1,6 +1,8 @@
package dev.adventurecraft.awakening.common;
-import dev.adventurecraft.awakening.extension.entity.block.ExSignBlockEntity;
+import dev.adventurecraft.awakening.common.instruments.IInstrumentConfig;
+import dev.adventurecraft.awakening.common.instruments.SimpleInstrumentConfig;
+import dev.adventurecraft.awakening.extension.entity.block.ExSongContainer;
import net.minecraft.block.Block;
import net.minecraft.entity.block.SignBlockEntity;
import net.minecraft.entity.player.PlayerEntity;
@@ -10,26 +12,60 @@
public class AC_ItemInstrument extends Item {
- String instrument;
- protected AC_ItemInstrument(int var1, String var2) {
- super(var1);
- this.instrument = var2;
+ /**
+ * The sound's URI.
+ * To play, for example, resources/newsound/note/harp.ogg, the instrument would be "note.harp"
.
+ */
+ IInstrumentConfig instrument;
+
+ /**
+ * Creates a new instrument item.
+ *
+ * @param itemId The ID of the item.
+ * @param instrumentUri The instrument's sound URI. Default tuning is +3
+ */
+ protected AC_ItemInstrument(int itemId, String instrumentUri) {
+ super(itemId);
+ this.instrument = new SimpleInstrumentConfig(instrumentUri);
+ }
+
+ /**
+ * Creates a new instrument item.
+ *
+ * @param itemId The ID of the item.
+ * @param instrumentUri The instrument's sound URI.
+ * @param noteOffset The offset of the instrument to be tuned to match with the pentagram
+ */
+ protected AC_ItemInstrument(int itemId, String instrumentUri, int noteOffset) {
+ super(itemId);
+ this.instrument = new SimpleInstrumentConfig(instrumentUri, noteOffset);
+ }
+
+ /**
+ * Creates a new instrument item.
+ *
+ * @param itemId The ID of the item.
+ * @param instrumentConfig The instrument config that the instrument will use
+ */
+ protected AC_ItemInstrument(int itemId, IInstrumentConfig instrumentConfig) {
+ super(itemId);
+ this.instrument = instrumentConfig;
}
@Override
- public boolean useOnBlock(ItemStack var1, PlayerEntity var2, World world, int targetBlockX, int targetBlockY, int targetBlockZ, int var7) {
- if (world.getBlockId(targetBlockX, targetBlockY, targetBlockZ) == Block.STANDING_SIGN.id) {
- var targetSign = (SignBlockEntity) world.getBlockEntity(targetBlockX, targetBlockY, targetBlockZ);
- ((ExSignBlockEntity) targetSign).playSong(this.instrument);
+ public boolean useOnBlock(ItemStack stack, PlayerEntity player, World world, int x, int y, int z, int side) {
+ if (world.getBlockId(x, y, z) == Block.STANDING_SIGN.id) {
+ var targetSign = (SignBlockEntity) world.getBlockEntity(x, y, z);
+ ((ExSongContainer) targetSign).playSong(this.instrument);
}
return false;
}
@Override
- public ItemStack use(ItemStack var1, World var2, PlayerEntity var3) {
+ public ItemStack use(ItemStack stack, World world, PlayerEntity player) {
AC_GuiMusicSheet.showUI(this.instrument);
- return var1;
+ return stack;
}
}
diff --git a/src/main/java/dev/adventurecraft/awakening/common/MusicPlayer.java b/src/main/java/dev/adventurecraft/awakening/common/MusicPlayer.java
index 67c4dcf2..3a53a40f 100644
--- a/src/main/java/dev/adventurecraft/awakening/common/MusicPlayer.java
+++ b/src/main/java/dev/adventurecraft/awakening/common/MusicPlayer.java
@@ -1,143 +1,38 @@
package dev.adventurecraft.awakening.common;
+import dev.adventurecraft.awakening.common.instruments.IInstrumentConfig;
+import dev.adventurecraft.awakening.common.instruments.Note;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
public class MusicPlayer {
-
/**
- * @param world The world in which the note will be played
- * @param sourceEntity The entity from which the location will be taken to play the note
- * @param instrumentString The instrument name from which the sound will be taken
- * @param noteChar The note character from A to G
- * @param isSharp Whether the note should be played half a step higher
- * @param basePitchModifier How much should the pitch be altered for the given note
- * @param volume The volume of this note
+ * @param world The world where the sound will be played
+ * @param x The X position in said world
+ * @param y The Y position in said world
+ * @param z The Z position in said world
+ * @param instrumentConfig The instrument to be used to play the note
+ * @param note The note to be played
+ * @param volume The volume that the note will be played at
*/
- public static void playNoteFromEntity(World world, Entity sourceEntity, String instrumentString, char noteChar, boolean isSharp, float basePitchModifier, float volume) {
- playNote(world, sourceEntity.x, sourceEntity.y, sourceEntity.z, instrumentString, noteChar, isSharp, basePitchModifier, volume);
+ public static void playNote(World world, double x, double y, double z, IInstrumentConfig instrumentConfig, Note note, float volume) {
+ playNote(world, x, y, z, instrumentConfig.getSoundString(note), instrumentConfig.getPitchModifier() * note.getPitch(), instrumentConfig.getVolumeModifier() * volume);
}
/**
- * @param targetWorld The world in which the note will be played
- * @param worldXPos The X position of the sound
- * @param worldYPos The Y position of the sound
- * @param worldZPos The Z position of the sound
- * @param instrumentString The instrument name from which the sound will be taken
- * @param noteChar The note character from A to G
- * @param isSharp Whether the note should be played half a step higher
- * @param basePitchModifier How much should the pitch be altered for the given note
- * @param volume The volume of this note
+ * @param world The world where the sound will be played
+ * @param x The X position in said world
+ * @param y The Y position in said world
+ * @param z The Z position in said world
+ * @param soundURI The instrument to be used on playing the note
+ * @param pitchMod The note to be played
+ * @param volume The volume that the note will be played at
*/
- public static void playNote(World targetWorld, double worldXPos, double worldYPos, double worldZPos, String instrumentString, char noteChar, boolean isSharp, float basePitchModifier, float volume) {
- float noteFrequency = 1.189207F; // Mod to F# to be A
- switch (noteChar) { // Mod to A to be whatever note was played
- case 'A':
- break;
- case 'B':
- noteFrequency *= 1.122462F;
- break;
- case 'C':
- noteFrequency *= 1.189207F;
- break;
- case 'D':
- noteFrequency *= 1.33484F;
- break;
- case 'E':
- noteFrequency *= 1.498307F;
- break;
- case 'F':
- noteFrequency *= 1.587401F;
- break;
- case 'G':
- noteFrequency *= 1.781797F;
- break;
- default:
- return;
- }
-
- if (isSharp) {
- noteFrequency = (float) ((double) noteFrequency * 1.059463D); // Mod to the note that was played to give it half a step upwards
- }
-
- targetWorld.playSound(worldXPos, worldYPos, worldZPos, instrumentString, volume, noteFrequency * basePitchModifier);
- }
-
- /**
- * @param targetWorld The world where the note will be played
- * @param worldXPos The x position in the world where the note will be played
- * @param worldYPos The y position in the world where the note will be played
- * @param worldZPos The z position in the world where the note will be played
- * @param instrumentString The instrument that will be played
- * @param songString The string that contains the song
- * @param noteIndex The note to be played
- * @param volume The volume in which the song will be played
- */
- public static void playNoteFromSong(World targetWorld, double worldXPos, double worldYPos, double worldZPos, String instrumentString, String songString, int noteIndex, float volume) {
- int stringIterationIndex = 0; // Current index on the string iteration
- int noteIterationIndex = 0; // Current note of the song
- boolean isFlat = false;
- boolean isSharp = false;
- char noteToPlay = 'A';
-
- float basePitchModifier;
- char iterationChar;
-
- // Count the octave changes before up to the current note
- for (basePitchModifier = 1.0F; noteIterationIndex <= noteIndex && stringIterationIndex < songString.length(); ++stringIterationIndex) {
- iterationChar = songString.charAt(stringIterationIndex);
- if (iterationChar == '+') { // Increase the octave of the note
- basePitchModifier *= 2.0F;
- } else if (iterationChar == '-') { // Lower the octave of the note
- basePitchModifier *= 0.5F;
- } else if (iterationChar != '#' && iterationChar != 'b') { // Ignore sharps and flats
- noteToPlay = iterationChar; // Set this as the current note
- ++noteIterationIndex;
- }
- }
-
-
- // Check the next character for a sharp or a flat (if it can exist)
- if (stringIterationIndex < songString.length()) {
- iterationChar = songString.charAt(stringIterationIndex);
- if (iterationChar == '#') {
- isSharp = true;
- } else if (iterationChar == 'b') {
- isFlat = true;
- }
- }
-
- // Translate all flats to sharps instead, by reducing its char value (or rolling over if it's A, the lowest ASCII).
- if (isFlat) {
- if (noteToPlay == 'A') {
- basePitchModifier *= 0.5F;
- noteToPlay = 'G';
- } else {
- --noteToPlay;
- }
-
- isSharp = true;
- }
-
- // Finally play that note
- playNote(targetWorld, worldXPos, worldYPos, worldZPos, instrumentString, noteToPlay, isSharp, basePitchModifier, volume);
+ public static void playNote(World world, double x, double y, double z, String soundURI, float pitchMod, float volume) {
+ world.playSound(x, y, z, soundURI, volume, pitchMod);
}
- /**
- * @param songString The string representation of the song
- * @return the amount of notes in the string
- */
- public static int countNotes(String songString) {
- int i = 0;
-
- int noteCount;
- for (noteCount = 0; i < songString.length(); ++i) {
- char currentNote = songString.charAt(i);
- if (currentNote != '+' && currentNote != '-' && currentNote != '#' && currentNote != 'b') {
- ++noteCount;
- }
- }
-
- return noteCount;
+ public static void playNoteFromEntity(Entity entity, IInstrumentConfig instrumentConfig, Note note, float volume) {
+ playNote(entity.world, entity.x, entity.y, entity.z, instrumentConfig, note, volume);
}
}
diff --git a/src/main/java/dev/adventurecraft/awakening/common/instruments/IInstrumentConfig.java b/src/main/java/dev/adventurecraft/awakening/common/instruments/IInstrumentConfig.java
new file mode 100644
index 00000000..37856eab
--- /dev/null
+++ b/src/main/java/dev/adventurecraft/awakening/common/instruments/IInstrumentConfig.java
@@ -0,0 +1,11 @@
+package dev.adventurecraft.awakening.common.instruments;
+
+public interface IInstrumentConfig {
+ String getSoundString(Note note);
+
+ float getPitchModifier();
+
+ float getVolumeModifier();
+
+ int getTuning();
+}
diff --git a/src/main/java/dev/adventurecraft/awakening/common/instruments/Note.java b/src/main/java/dev/adventurecraft/awakening/common/instruments/Note.java
new file mode 100644
index 00000000..67c72596
--- /dev/null
+++ b/src/main/java/dev/adventurecraft/awakening/common/instruments/Note.java
@@ -0,0 +1,105 @@
+package dev.adventurecraft.awakening.common.instruments;
+
+/**
+ * Represents a frequency of a standard note.
+ * A note of value 3 and octave 4 is the middle C.
+ */
+public class Note {
+
+ /**
+ * Precalculated values 0 to 11 of note coefficients.
+ * Wikipedia Link
+ */
+ private static final double[] noteCoefficient = {
+ 1,
+ 1.0594630943592952646D,
+ 1.122462048309372981514422431964D,
+ 1.1892071150027210668460489434449D,
+ 1.25992104989487316494880113073D,
+ 1.3348398541700343650713174535376D,
+ 1.4142135623730950491074314305706D,
+ 1.4983070768766814991771910314151D,
+ 1.5874010519681994752092850851889D,
+ 1.6817928305074290866076380551132D,
+ 1.7817974362806786101224718638408D,
+ 1.8877486253633869940320418208842D,
+ };
+
+ /**
+ * A list that maps the characters 'A' through 'G' to a base 0 note.
+ */
+ private static final int[] charToNote = {0, 2, 3, 5, 7, 8, 10};
+
+ private int value;
+
+ /**
+ * The octave of the note.
+ */
+ public int octave;
+
+ private static final int baseOctave = 4;
+
+ /**
+ * Creates a note starting out from the 4th octave.
+ *
+ * @param value The value of the note.
+ */
+ public Note(int value) {
+ this(value, baseOctave);
+ }
+
+
+ /**
+ * @param sourceChar The note's source character. 'A'
for 0.
+ * Invalid chars are set to 0.
+ */
+ public Note(char sourceChar, int octave) {
+ this((sourceChar >= 'A' && sourceChar <= 'G') ? (charToNote[sourceChar - 'A']) : 0, octave);
+ }
+
+ public Note(int value, int octave) {
+ this.octave = octave;
+ this.setValue(value);
+ }
+
+
+ /**
+ * @return The change in pitch of the note to be played
+ */
+ public float getPitch() {
+ float product = (float) Math.pow(2, octave);
+ return (float) (noteCoefficient[this.getValue()] * product);
+ }
+
+ public void shiftValue(int amount) {
+ this.setValue(this.getValue() + amount);
+ }
+
+ public Note withShiftedValue(int amount) {
+ return new Note(this.getValue() + amount, this.octave);
+ }
+
+ /**
+ * The value of the note.
+ * 0 for A
+ * 1 for A#
+ * 2 for D
+ * 10 for G
+ * and 11 for G#
+ */
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ while (value < 0) {
+ value += 12;
+ octave -= 1;
+ }
+ while (value > 11) {
+ value -= 12;
+ octave += 1;
+ }
+ this.value = value;
+ }
+}
diff --git a/src/main/java/dev/adventurecraft/awakening/common/instruments/SimpleInstrumentConfig.java b/src/main/java/dev/adventurecraft/awakening/common/instruments/SimpleInstrumentConfig.java
new file mode 100644
index 00000000..7bdc260f
--- /dev/null
+++ b/src/main/java/dev/adventurecraft/awakening/common/instruments/SimpleInstrumentConfig.java
@@ -0,0 +1,36 @@
+package dev.adventurecraft.awakening.common.instruments;
+
+public class SimpleInstrumentConfig implements IInstrumentConfig {
+
+ public final String soundURI;
+ public final int tuning;
+
+ public SimpleInstrumentConfig(String soundURI) {
+ this(soundURI, 3);
+ }
+
+ public SimpleInstrumentConfig(String soundURI, int sampleNote) {
+ this.soundURI = soundURI;
+ this.tuning = sampleNote;
+ }
+
+ @Override
+ public String getSoundString(Note note) {
+ return soundURI;
+ }
+
+ @Override
+ public float getPitchModifier() {
+ return 1;
+ }
+
+ @Override
+ public float getVolumeModifier() {
+ return 1;
+ }
+
+ @Override
+ public int getTuning() {
+ return tuning;
+ }
+}
diff --git a/src/main/java/dev/adventurecraft/awakening/common/instruments/Song.java b/src/main/java/dev/adventurecraft/awakening/common/instruments/Song.java
new file mode 100644
index 00000000..625e37f1
--- /dev/null
+++ b/src/main/java/dev/adventurecraft/awakening/common/instruments/Song.java
@@ -0,0 +1,76 @@
+package dev.adventurecraft.awakening.common.instruments;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A list of notes that can be played.
+ */
+public class Song implements Iterable {
+
+ private static final char SHARP = '#';
+ private static final char FLAT = 'b';
+ private static final char RAISE_OCTAVE = '+';
+ private static final char LOWER_OCTAVE = '-';
+
+ /**
+ * A list of notes. If a given note is null it is not meant to be played.
+ */
+ private final List notes;
+
+ public Song(String sourceString, int baseShift) {
+ // Initialize the list
+ this.notes = new ArrayList<>();
+ int currentOctave = 0;
+ int noteCount = 0;
+ // Loop through the chars of the song
+ for (int i = 0; i < sourceString.length(); i++) {
+ char currentChar = sourceString.charAt(i);
+
+ if (charIsANote(currentChar)) {
+ Note newNote = new Note(currentChar, currentOctave);
+ newNote.shiftValue(baseShift);
+ this.notes.add(newNote);
+ noteCount++;
+ } else {
+ switch (currentChar) {
+ case RAISE_OCTAVE -> currentOctave += 1;
+ case LOWER_OCTAVE -> currentOctave -= 1;
+ case SHARP -> {
+ if (noteCount > 0) {
+ this.notes.get(noteCount - 1).shiftValue(1);
+ }
+ }
+ case FLAT -> {
+ if (noteCount > 0) {
+ this.notes.get(noteCount - 1).shiftValue(-1);
+ }
+ }
+ default -> this.notes.add(null);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param checkChar The char to be checked
+ * @return Whether the character represents a note (A-G)
+ */
+ private boolean charIsANote(char checkChar) {
+ return checkChar >= 'A' && checkChar <= 'G';
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ return notes.iterator();
+ }
+}
diff --git a/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSignBlockEntity.java b/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSignBlockEntity.java
deleted file mode 100644
index 3aca7e20..00000000
--- a/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSignBlockEntity.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package dev.adventurecraft.awakening.extension.entity.block;
-
-public interface ExSignBlockEntity {
-
- void playSong(String instrumentString);
-}
diff --git a/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSongContainer.java b/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSongContainer.java
new file mode 100644
index 00000000..2d8f9776
--- /dev/null
+++ b/src/main/java/dev/adventurecraft/awakening/extension/entity/block/ExSongContainer.java
@@ -0,0 +1,15 @@
+package dev.adventurecraft.awakening.extension.entity.block;
+
+import dev.adventurecraft.awakening.common.instruments.IInstrumentConfig;
+
+public interface ExSongContainer {
+
+ /**
+ * Plays the stored song with the given instrument string.
+ *
+ * @param instrumentUri the instrument's uri, the sound from the files that will be played.
+ */
+ void playSong(IInstrumentConfig instrumentUri);
+
+ String getSong();
+}
diff --git a/src/main/java/dev/adventurecraft/awakening/mixin/entity/block/MixinSignBlockEntity.java b/src/main/java/dev/adventurecraft/awakening/mixin/entity/block/MixinSignBlockEntity.java
index c53df0a2..55519d8d 100644
--- a/src/main/java/dev/adventurecraft/awakening/mixin/entity/block/MixinSignBlockEntity.java
+++ b/src/main/java/dev/adventurecraft/awakening/mixin/entity/block/MixinSignBlockEntity.java
@@ -1,22 +1,28 @@
package dev.adventurecraft.awakening.mixin.entity.block;
import dev.adventurecraft.awakening.common.MusicPlayer;
-import dev.adventurecraft.awakening.extension.entity.block.ExSignBlockEntity;
+import dev.adventurecraft.awakening.common.instruments.IInstrumentConfig;
+import dev.adventurecraft.awakening.common.instruments.Note;
+import dev.adventurecraft.awakening.common.instruments.Song;
+import dev.adventurecraft.awakening.extension.entity.block.ExSongContainer;
import net.minecraft.entity.BlockEntity;
import net.minecraft.entity.block.SignBlockEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
+import java.util.Iterator;
+
@Mixin(SignBlockEntity.class)
-public abstract class MixinSignBlockEntity extends BlockEntity implements ExSignBlockEntity {
+public abstract class MixinSignBlockEntity extends BlockEntity implements ExSongContainer {
@Shadow
public String[] text;
public boolean playSong;
- public String instrument;
- public int onNote;
+ public IInstrumentConfig instrument;
public int tickSinceStart;
+ public Iterator songIterator;
+
@Override
public void tick() {
if (!this.playSong) {
@@ -24,12 +30,11 @@ public void tick() {
}
if (this.tickSinceStart % 10 == 0) {
- String signContents = this.text[0] + this.text[1] + this.text[2] + this.text[3];
- if (this.onNote < MusicPlayer.countNotes(signContents)) {
- MusicPlayer.playNoteFromSong(this.world, this.x, this.y, this.z, this.instrument, signContents, this.onNote, 1.0F);
- ++this.onNote;
- } else {
- this.playSong = false;
+ if (!songIterator.hasNext()) this.playSong = false;
+ else {
+ Note currentNote = songIterator.next();
+ if (currentNote != null)
+ MusicPlayer.playNote(this.world, this.x, this.y, this.z, this.instrument, currentNote, 1.0F);
}
}
@@ -37,10 +42,16 @@ public void tick() {
}
@Override
- public void playSong(String instrumentString) {
+ public void playSong(IInstrumentConfig instrumentConfig) {
this.playSong = true;
- this.instrument = instrumentString;
+ this.instrument = instrumentConfig;
this.tickSinceStart = 0;
- this.onNote = 0;
+
+ Song songToPlay = new Song(getSong(), instrumentConfig.getTuning());
+ this.songIterator = songToPlay.iterator();
+ }
+
+ public String getSong() {
+ return this.text[0] + this.text[1] + this.text[2] + this.text[3];
}
}