github.com/df-mc/dragonfly@v0.9.13/server/block/note.go (about)

     1  package block
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/block/cube"
     5  	"github.com/df-mc/dragonfly/server/internal/nbtconv"
     6  	"github.com/df-mc/dragonfly/server/item"
     7  	"github.com/df-mc/dragonfly/server/world"
     8  	"github.com/df-mc/dragonfly/server/world/particle"
     9  	"github.com/df-mc/dragonfly/server/world/sound"
    10  	"time"
    11  )
    12  
    13  // Note is a musical block that emits sounds when powered with redstone.
    14  type Note struct {
    15  	solid
    16  	bass
    17  
    18  	// Pitch is the current pitch the note block is set to. Value ranges from 0-24.
    19  	Pitch int
    20  }
    21  
    22  // playNote ...
    23  func (n Note) playNote(pos cube.Pos, w *world.World) {
    24  	w.PlaySound(pos.Vec3(), sound.Note{Instrument: n.instrument(pos, w), Pitch: n.Pitch})
    25  	w.AddParticle(pos.Vec3(), particle.Note{Instrument: n.Instrument(), Pitch: n.Pitch})
    26  }
    27  
    28  // updateInstrument ...
    29  func (n Note) instrument(pos cube.Pos, w *world.World) sound.Instrument {
    30  	if instrumentBlock, ok := w.Block(pos.Side(cube.FaceDown)).(interface {
    31  		Instrument() sound.Instrument
    32  	}); ok {
    33  		return instrumentBlock.Instrument()
    34  	}
    35  	return sound.Piano()
    36  }
    37  
    38  // DecodeNBT ...
    39  func (n Note) DecodeNBT(data map[string]any) any {
    40  	n.Pitch = int(nbtconv.Uint8(data, "note"))
    41  	return n
    42  }
    43  
    44  // EncodeNBT ...
    45  func (n Note) EncodeNBT() map[string]any {
    46  	return map[string]any{"note": byte(n.Pitch)}
    47  }
    48  
    49  // Activate ...
    50  func (n Note) Activate(pos cube.Pos, _ cube.Face, w *world.World, _ item.User, _ *item.UseContext) bool {
    51  	if _, ok := w.Block(pos.Side(cube.FaceUp)).(Air); !ok {
    52  		return false
    53  	}
    54  	n.Pitch = (n.Pitch + 1) % 25
    55  	n.playNote(pos, w)
    56  	w.SetBlock(pos, n, &world.SetOpts{DisableBlockUpdates: true, DisableLiquidDisplacement: true})
    57  	return true
    58  }
    59  
    60  // BreakInfo ...
    61  func (n Note) BreakInfo() BreakInfo {
    62  	return newBreakInfo(0.8, alwaysHarvestable, axeEffective, oneOf(n))
    63  }
    64  
    65  // FuelInfo ...
    66  func (Note) FuelInfo() item.FuelInfo {
    67  	return newFuelInfo(time.Second * 15)
    68  }
    69  
    70  // EncodeItem ...
    71  func (n Note) EncodeItem() (name string, meta int16) {
    72  	return "minecraft:noteblock", 0
    73  }
    74  
    75  // EncodeBlock ...
    76  func (n Note) EncodeBlock() (name string, properties map[string]any) {
    77  	return "minecraft:noteblock", nil
    78  }