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  }