74 lines
3.3 KiB
Java
74 lines
3.3 KiB
Java
package de.mviper.adventskalender.christmas;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Sound;
|
|
import org.bukkit.SoundCategory;
|
|
import org.bukkit.World;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
import java.util.Collection;
|
|
import java.util.function.Supplier;
|
|
|
|
/** Spielt Weihnachtsmelodien mit Glocken (Notenblock-Klaenge, keine Dateien noetig). */
|
|
final class SantaMelody {
|
|
// Melodie: {Halbtoene ueber C4, Dauer in Achteln (1 = Achtel)}
|
|
private static final int[][] JINGLE = {
|
|
{4, 2}, {4, 2}, {4, 4}, {4, 2}, {4, 2}, {4, 4}, {4, 2}, {7, 2}, {0, 3}, {2, 1}, {4, 8},
|
|
{5, 2}, {5, 2}, {5, 3}, {5, 1}, {5, 2}, {4, 2}, {4, 2}, {4, 1}, {4, 1}, {4, 2}, {2, 2}, {2, 2}, {4, 2}, {2, 4}, {7, 4},
|
|
{4, 2}, {4, 2}, {4, 4}, {4, 2}, {4, 2}, {4, 4}, {4, 2}, {7, 2}, {0, 3}, {2, 1}, {4, 8},
|
|
{5, 2}, {5, 2}, {5, 3}, {5, 1}, {5, 2}, {4, 2}, {4, 2}, {4, 1}, {4, 1}, {7, 2}, {7, 2}, {5, 2}, {2, 2}, {0, 8},
|
|
};
|
|
// "We Wish You a Merry Christmas"
|
|
private static final int[][] WISH = {
|
|
{2, 2}, {7, 2}, {7, 1}, {9, 1}, {7, 1}, {6, 1}, {4, 2}, {4, 2}, {4, 2}, {9, 2}, {9, 1}, {11, 1}, {9, 1}, {7, 1},
|
|
{6, 2}, {2, 2}, {2, 2}, {11, 2}, {11, 1}, {12, 1}, {11, 1}, {9, 1}, {7, 2}, {4, 2}, {2, 1}, {2, 1}, {4, 2},
|
|
{9, 2}, {6, 2}, {7, 6},
|
|
};
|
|
static final int[][][] TUNES = {JINGLE, WISH};
|
|
|
|
private final ChristmasManager mgr;
|
|
private BukkitTask task;
|
|
|
|
SantaMelody(ChristmasManager mgr) { this.mgr = mgr; }
|
|
|
|
boolean playing() { return task != null; }
|
|
|
|
/** Santa-Event: Melodie fuer die Spieler der Welt (oder alle, santa.melody.everyone). */
|
|
void play(World world) {
|
|
if (!mgr.cfg().getBoolean("santa.melody.enable", true)) return;
|
|
final boolean everyone = mgr.cfg().getBoolean("santa.melody.everyone", false);
|
|
final float volume = (float) mgr.cfg().getDouble("santa.melody.volume", 1.0);
|
|
final int tempo = Math.max(1, mgr.cfg().getInt("santa.melody.tempo", 3));
|
|
play(() -> everyone ? Bukkit.getOnlinePlayers() : world.getPlayers(), 0, volume, tempo, null);
|
|
}
|
|
|
|
/** Spielt eine Melodie fuer ein sich aenderndes Publikum; done wird nach dem letzten Ton aufgerufen. */
|
|
void play(Supplier<Collection<? extends Player>> audience, int tune, float volume, int tempo, Runnable done) {
|
|
stop();
|
|
final int[][] notes = TUNES[Math.floorMod(tune, TUNES.length)];
|
|
final int[] pos = {0};
|
|
final int[] wait = {0};
|
|
task = Bukkit.getScheduler().runTaskTimer(mgr.plugin(), () -> {
|
|
if (wait[0]-- > 0) return;
|
|
if (pos[0] >= notes.length) {
|
|
stop();
|
|
if (done != null) done.run();
|
|
return;
|
|
}
|
|
int[] n = notes[pos[0]++];
|
|
float pitch = (float) Math.pow(2.0, (n[0] + 6 - 12) / 12.0); // C4 = Notenblock-Ton 6
|
|
for (Player p : audience.get()) {
|
|
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_BELL, SoundCategory.RECORDS, volume, pitch);
|
|
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, SoundCategory.RECORDS, volume * 0.5f, pitch);
|
|
}
|
|
wait[0] = n[1] * tempo - 1;
|
|
}, 10L, 1L);
|
|
}
|
|
|
|
void stop() {
|
|
if (task != null) task.cancel();
|
|
task = null;
|
|
}
|
|
}
|