github.com/df-mc/dragonfly@v0.9.13/server/block/ender_chest.go (about) 1 package block 2 3 import ( 4 "github.com/df-mc/atomic" 5 "github.com/df-mc/dragonfly/server/block/cube" 6 "github.com/df-mc/dragonfly/server/item" 7 "github.com/df-mc/dragonfly/server/item/inventory" 8 "github.com/df-mc/dragonfly/server/world" 9 "github.com/df-mc/dragonfly/server/world/sound" 10 "github.com/go-gl/mathgl/mgl64" 11 ) 12 13 // enderChestOwner represents an entity that has an ender chest inventory. 14 type enderChestOwner interface { 15 ContainerOpener 16 EnderChestInventory() *inventory.Inventory 17 } 18 19 // EnderChest is a type of chest whose contents are exclusive to each player, and can be accessed from anywhere. 20 // The empty value of EnderChest is not valid. It must be created using block.NewEnderChest(). 21 type EnderChest struct { 22 chest 23 transparent 24 bass 25 sourceWaterDisplacer 26 27 // Facing is the direction that the ender chest is facing. 28 Facing cube.Direction 29 30 viewers *atomic.Int64 31 } 32 33 // NewEnderChest creates a new initialised ender chest. 34 func NewEnderChest() EnderChest { 35 return EnderChest{viewers: atomic.NewInt64(0)} 36 } 37 38 // BreakInfo ... 39 func (c EnderChest) BreakInfo() BreakInfo { 40 return newBreakInfo(22.5, pickaxeHarvestable, pickaxeEffective, silkTouchDrop(item.NewStack(Obsidian{}, 8), item.NewStack(NewEnderChest(), 1))).withBlastResistance(3000) 41 } 42 43 // LightEmissionLevel ... 44 func (c EnderChest) LightEmissionLevel() uint8 { 45 return 7 46 } 47 48 // SideClosed ... 49 func (EnderChest) SideClosed(cube.Pos, cube.Pos, *world.World) bool { 50 return false 51 } 52 53 // UseOnBlock ... 54 func (c EnderChest) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) (used bool) { 55 pos, _, used = firstReplaceable(w, pos, face, c) 56 if !used { 57 return 58 } 59 //noinspection GoAssignmentToReceiver 60 c = NewEnderChest() 61 c.Facing = user.Rotation().Direction().Opposite() 62 63 place(w, pos, c, user, ctx) 64 return placed(ctx) 65 } 66 67 // Activate ... 68 func (c EnderChest) Activate(pos cube.Pos, _ cube.Face, _ *world.World, u item.User, _ *item.UseContext) bool { 69 if opener, ok := u.(enderChestOwner); ok { 70 opener.OpenBlockContainer(pos) 71 return true 72 } 73 return false 74 } 75 76 // AddViewer ... 77 func (c EnderChest) AddViewer(w *world.World, pos cube.Pos) { 78 if c.viewers.Inc() == 1 { 79 c.open(w, pos) 80 } 81 } 82 83 // RemoveViewer ... 84 func (c EnderChest) RemoveViewer(w *world.World, pos cube.Pos) { 85 if c.viewers.Load() == 0 { 86 return 87 } 88 if c.viewers.Dec() == 0 { 89 c.close(w, pos) 90 } 91 } 92 93 // open opens the ender chest, displaying the animation and playing a sound. 94 func (c EnderChest) open(w *world.World, pos cube.Pos) { 95 for _, v := range w.Viewers(pos.Vec3()) { 96 v.ViewBlockAction(pos, OpenAction{}) 97 } 98 w.PlaySound(pos.Vec3Centre(), sound.ChestOpen{}) 99 } 100 101 // close closes the ender chest, displaying the animation and playing a sound. 102 func (c EnderChest) close(w *world.World, pos cube.Pos) { 103 for _, v := range w.Viewers(pos.Vec3()) { 104 v.ViewBlockAction(pos, CloseAction{}) 105 } 106 w.PlaySound(pos.Vec3Centre(), sound.ChestClose{}) 107 } 108 109 // EncodeNBT ... 110 func (c EnderChest) EncodeNBT() map[string]interface{} { 111 return map[string]interface{}{"id": "EnderChest"} 112 } 113 114 // DecodeNBT ... 115 func (c EnderChest) DecodeNBT(map[string]interface{}) interface{} { 116 return NewEnderChest() 117 } 118 119 // EncodeItem ... 120 func (EnderChest) EncodeItem() (name string, meta int16) { 121 return "minecraft:ender_chest", 0 122 } 123 124 // EncodeBlock ... 125 func (c EnderChest) EncodeBlock() (name string, properties map[string]interface{}) { 126 return "minecraft:ender_chest", map[string]any{"minecraft:cardinal_direction": c.Facing.String()} 127 } 128 129 // allEnderChests ... 130 func allEnderChests() (chests []world.Block) { 131 for _, direction := range cube.Directions() { 132 chests = append(chests, EnderChest{Facing: direction}) 133 } 134 return 135 }