diff --git a/patches/minecraft/net/minecraft/block/BlockNote.java.patch b/patches/minecraft/net/minecraft/block/BlockNote.java.patch new file mode 100644 index 000000000..2ad648f11 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockNote.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockNote.java ++++ ../src-work/minecraft/net/minecraft/block/BlockNote.java +@@ -45,7 +45,9 @@ + + if (tileentitynote != null) + { ++ int old = tileentitynote.field_145879_a; + tileentitynote.func_145877_a(); ++ if (old == tileentitynote.field_145879_a) return false; + tileentitynote.func_145878_a(p_149727_1_, p_149727_2_, p_149727_3_, p_149727_4_); + } + +@@ -73,6 +75,11 @@ + + public boolean func_149696_a(World p_149696_1_, int p_149696_2_, int p_149696_3_, int p_149696_4_, int p_149696_5_, int p_149696_6_) + { ++ int meta = p_149696_1_.func_72805_g(p_149696_2_, p_149696_3_, p_149696_4_); ++ net.minecraftforge.event.world.NoteBlockEvent.Play e = new net.minecraftforge.event.world.NoteBlockEvent.Play(p_149696_1_, p_149696_2_, p_149696_3_, p_149696_4_, meta, p_149696_6_, p_149696_5_); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(e)) return false; ++ p_149696_5_ = e.instrument.ordinal(); ++ p_149696_6_ = e.getVanillaNoteId(); + float f = (float)Math.pow(2.0D, (double)(p_149696_6_ - 12) / 12.0D); + String s = "harp"; + diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch new file mode 100644 index 000000000..908a0d8cb --- /dev/null +++ b/patches/minecraft/net/minecraft/tileentity/TileEntityNote.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityNote.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityNote.java +@@ -35,7 +35,9 @@ + + public void func_145877_a() + { ++ byte old = field_145879_a; + this.field_145879_a = (byte)((this.field_145879_a + 1) % 25); ++ if (!net.minecraftforge.common.ForgeHooks.onNoteChange(this, old)) return; + this.func_70296_d(); + } + diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 3ebb8f7ad..6e619dd9a 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -3,6 +3,7 @@ package net.minecraftforge.common; import java.util.ArrayList; import java.util.List; import java.util.Set; + import cpw.mods.fml.common.eventhandler.Event; import cpw.mods.fml.relauncher.ReflectionHelper; import net.minecraft.block.Block; @@ -25,6 +26,7 @@ import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityNote; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.DamageSource; @@ -47,6 +49,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; import net.minecraftforge.event.entity.player.PlayerOpenContainerEvent; import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.NoteBlockEvent; import static net.minecraft.init.Blocks.*; public class ForgeHooks @@ -436,4 +439,16 @@ public class ForgeHooks container.maximumCost = e.cost; return false; } + + public static boolean onNoteChange(TileEntityNote te, byte old) + { + NoteBlockEvent.Change e = new NoteBlockEvent.Change(te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord, te.getBlockMetadata(), old, te.note); + if (MinecraftForge.EVENT_BUS.post(e)) + { + te.note = old; + return false; + } + te.note = (byte)e.getVanillaNoteId(); + return true; + } } diff --git a/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java b/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java new file mode 100644 index 000000000..6916ca0b1 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java @@ -0,0 +1,165 @@ +package net.minecraftforge.event.world; + +import com.google.common.base.Preconditions; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import net.minecraftforge.event.world.BlockEvent; +import cpw.mods.fml.common.eventhandler.Cancelable; +import cpw.mods.fml.common.eventhandler.Event; + +/** + * Base class for Noteblock Events + * + */ +public class NoteBlockEvent extends BlockEvent +{ + private int noteId; + + NoteBlockEvent(World world, int x, int y, int z, int meta, int note) + { + super(x, y, z, world, Blocks.noteblock, meta); + this.noteId = note; + } + + /** + * Get the Note the Noteblock is tuned to + * @return the Note + */ + public Note getNote() + { + return Note.fromId(noteId); + } + + /** + * Get the Octave of the note this Noteblock is tuned to + * @return the Octave + */ + public Octave getOctave() + { + return Octave.fromId(noteId); + } + + /** + * get the vanilla note-id, which contains information about both Note and Octave. Most modders should not need this. + * @return an ID for the note + */ + public int getVanillaNoteId() + { + return noteId; + } + + /** + * Set Note and Octave for this event.
+ * If octave is Octave.HIGH, note may only be Note.F_SHARP + * @param note the Note + * @param octave the Octave + */ + public void setNote(Note note, Octave octave) + { + Preconditions.checkArgument(octave != Octave.HIGH || note == Note.F_SHARP, "Octave.HIGH is only valid for Note.F_SHARP!"); + this.noteId = note.ordinal() + octave.ordinal() * 12; + } + + /** + * Fired when a Noteblock plays it's note. You can override the note and instrument + * Canceling this event will stop the note from playing. + */ + @Cancelable + public static class Play extends NoteBlockEvent + { + public Instrument instrument; + + public Play(World world, int x, int y, int z, int meta, int note, int instrument) + { + super(world, x, y, z, meta, note); + this.instrument = Instrument.fromId(instrument); + } + } + + /** + * Fired when a Noteblock is changed. You can adjust the note it will change to via {@link #setNote(Note, Octave)}. + * Canceling this event will not change the note and also stop the Noteblock from playing it's note. + */ + @Cancelable + public static class Change extends NoteBlockEvent + { + public final Note oldNote; + public final Octave oldOctave; + + public Change(World world, int x, int y, int z, int meta, int oldNote, int newNote) + { + super(world, x, y, z, meta, newNote); + this.oldNote = Note.fromId(oldNote); + this.oldOctave = Octave.fromId(oldNote); + } + } + + /** + * Describes the types of musical Instruments that can be played by a Noteblock. + * The Instrument being played can be overridden with {@link NoteBlockEvent.Play#setInstrument(Instrument)} + */ + public static enum Instrument + { + PIANO, + BASSDRUM, + SNARE, + CLICKS, + BASSGUITAR; + + // cache to avoid creating a new array every time + private static final Instrument[] values = values(); + + static Instrument fromId(int id) + { + return id < 0 || id > 4 ? PIANO : values[id]; + } + } + + /** + * Information about the pitch of a Noteblock note. + * For altered notes such as G-Sharp / A-Flat the Sharp variant is used here. + * + */ + public static enum Note + { + F_SHARP, + G, + G_SHARP, + A, + A_SHARP, + B, + C, + C_SHARP, + D, + D_SHARP, + E, + F; + + private static final Note[] values = values(); + + static Note fromId(int id) + { + return values[id % 12]; + } + } + + /** + * Describes the Octave of a Note being played by a Noteblock. + * Together with {@link Note} it fully describes the note. + * + */ + public static enum Octave + { + LOW, + MID, + HIGH; // only valid for F_SHARP + + static Octave fromId(int id) + { + return id < 12 ? LOW : id == 24 ? HIGH : MID; + } + } + +} \ No newline at end of file