/* * CommandBook * Copyright (C) 2011 sk89q <http://www.sk89q.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.sk89q.jinglenote; import java.util.ArrayList; import java.util.List; import org.bukkit.Bukkit; import com.sk89q.commandbook.CommandBook; /** * @author Me4502 with code borrowed from CraftBook Extra */ public class StringJingleSequencer implements JingleSequencer { String tune; int delay; int position; int taskID; boolean isPlaying = false; List<Note> song; public StringJingleSequencer(String tune, int delay) { this.tune = tune; this.delay = delay; song = parseTune(tune); } @Override public void run(final JingleNotePlayer player) throws InterruptedException { position = 0; if (song == null) { return; } isPlaying = true; taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask( CommandBook.inst(), new Runnable() { @Override public void run() { if (position >= song.size()) { Bukkit.getScheduler().cancelTask(taskID); isPlaying = false; return; } player.play(song.get(position)); position++; } }, delay, delay); } public ArrayList<Note> parseTune(String tune) { if (tune == null) { return null; } ArrayList<Note> musicKeys = new ArrayList<Note>(); byte instrument = -1; for (int i = 0; i < tune.length(); i++) { char first = tune.charAt(i); if (first >= '0' && first <= '9') { // instrument? instrument = getTypeFromChar(first); } else if (i + 1 < tune.length()) { // note? if (instrument == -1) { return null; } int pitch = getPitchFromChar(first); boolean skip = false; if (pitch == -1) { switch (first) { case '-': case ' ': skip = true; break; default: return null; } } int octave; try { octave = Integer.parseInt(Character.toString(tune.charAt(i + 1))); } catch (NumberFormatException e) { octave = 2; } if (skip) { musicKeys.add(new Note(Instrument.PIANO, (byte) 0, 0)); if (octave == 0) { octave = 10; } } else { if (octave < 2) { octave = 2; } pitch += (octave - 2) * 12; if (pitch < 0) { pitch = 0; } else if (pitch > 24) { pitch = 24; } musicKeys.add(new Note(toMCSound(instrument), (byte) pitch, 60F)); } i++; } } if (musicKeys.size() == 0) { return null; } return musicKeys; } public byte getTypeFromChar(char type) { byte instrument = -1; switch (type) { case '9': case '8': case '7': case '0': instrument = 0; break; case '1': instrument = 1; break; case '2': instrument = 2; break; case '3': instrument = 3; break; case '4': instrument = 4; break; case '5': instrument = 5; break; case '6': instrument = 6; break; } return instrument; } public int getPitchFromChar(char charPitch) { int pitch = 0; switch (charPitch) { case 'f': pitch++; case 'e': pitch++; case 'D': pitch++; case 'd': pitch++; case 'C': pitch++; case 'c': pitch++; case 'b': pitch++; case 'A': pitch++; case 'a': pitch++; case 'G': pitch++; case 'g': pitch++; case 'F': break; default: pitch = -1; break; } return pitch; } protected Instrument toMCSound(byte instrument) { switch (instrument) { case 1: return Instrument.BASS_GUITAR; case 2: return Instrument.SNARE_DRUM; case 3: return Instrument.STICKS; case 4: return Instrument.BASS_DRUM; case 5: return Instrument.GUITAR; case 6: return Instrument.BASS; default: return Instrument.PIANO; } } @Override public void stop() { } public boolean isSongPlaying () { return isPlaying; } }