github.com/df-mc/dragonfly@v0.9.13/server/block/jukebox.go (about) 1 package block 2 3 import ( 4 "fmt" 5 "github.com/df-mc/dragonfly/server/block/cube" 6 "github.com/df-mc/dragonfly/server/internal/nbtconv" 7 "github.com/df-mc/dragonfly/server/item" 8 "github.com/df-mc/dragonfly/server/world" 9 "github.com/df-mc/dragonfly/server/world/sound" 10 "time" 11 ) 12 13 // Jukebox is a block used to play music discs. 14 type Jukebox struct { 15 solid 16 bass 17 18 // Item is the music disc played by the jukebox. 19 Item item.Stack 20 } 21 22 // FuelInfo ... 23 func (j Jukebox) FuelInfo() item.FuelInfo { 24 return newFuelInfo(time.Second * 15) 25 } 26 27 // BreakInfo ... 28 func (j Jukebox) BreakInfo() BreakInfo { 29 d := []item.Stack{item.NewStack(Jukebox{}, 1)} 30 if !j.Item.Empty() { 31 d = append(d, j.Item) 32 } 33 return newBreakInfo(0.8, alwaysHarvestable, axeEffective, simpleDrops(d...)).withBreakHandler(func(pos cube.Pos, w *world.World, u item.User) { 34 if _, hasDisc := j.Disc(); hasDisc { 35 w.PlaySound(pos.Vec3Centre(), sound.MusicDiscEnd{}) 36 } 37 }) 38 } 39 40 // jukeboxUser represents an item.User that can use a jukebox. 41 type jukeboxUser interface { 42 item.User 43 // SendJukeboxPopup sends a jukebox popup to the item.User. 44 SendJukeboxPopup(a ...any) 45 } 46 47 // Activate ... 48 func (j Jukebox) Activate(pos cube.Pos, _ cube.Face, w *world.World, u item.User, ctx *item.UseContext) bool { 49 if _, hasDisc := j.Disc(); hasDisc { 50 dropItem(w, j.Item, pos.Side(cube.FaceUp).Vec3Middle()) 51 52 j.Item = item.Stack{} 53 w.SetBlock(pos, j, nil) 54 w.PlaySound(pos.Vec3Centre(), sound.MusicDiscEnd{}) 55 } else if held, _ := u.HeldItems(); !held.Empty() { 56 if m, ok := held.Item().(item.MusicDisc); ok { 57 j.Item = held 58 59 w.SetBlock(pos, j, nil) 60 w.PlaySound(pos.Vec3Centre(), sound.MusicDiscEnd{}) 61 ctx.SubtractFromCount(1) 62 63 w.PlaySound(pos.Vec3Centre(), sound.MusicDiscPlay{DiscType: m.DiscType}) 64 if u, ok := u.(jukeboxUser); ok { 65 u.SendJukeboxPopup(fmt.Sprintf("Now playing: %v - %v", m.DiscType.Author(), m.DiscType.DisplayName())) 66 } 67 } 68 } 69 return true 70 } 71 72 // Disc returns the currently playing music disc 73 func (j Jukebox) Disc() (sound.DiscType, bool) { 74 if !j.Item.Empty() { 75 if m, ok := j.Item.Item().(item.MusicDisc); ok { 76 return m.DiscType, true 77 } 78 } 79 return sound.DiscType{}, false 80 } 81 82 // EncodeNBT ... 83 func (j Jukebox) EncodeNBT() map[string]any { 84 m := map[string]any{"id": "Jukebox"} 85 if _, hasDisc := j.Disc(); hasDisc { 86 m["RecordItem"] = nbtconv.WriteItem(j.Item, true) 87 } 88 return m 89 } 90 91 // DecodeNBT ... 92 func (j Jukebox) DecodeNBT(data map[string]any) any { 93 s := nbtconv.MapItem(data, "RecordItem") 94 if _, ok := s.Item().(item.MusicDisc); ok { 95 j.Item = s 96 } 97 return j 98 } 99 100 // EncodeItem ... 101 func (Jukebox) EncodeItem() (name string, meta int16) { 102 return "minecraft:jukebox", 0 103 } 104 105 // EncodeBlock ... 106 func (Jukebox) EncodeBlock() (string, map[string]any) { 107 return "minecraft:jukebox", nil 108 }