github.com/df-mc/dragonfly@v0.9.13/server/block/skull.go (about) 1 package block 2 3 import ( 4 "github.com/df-mc/dragonfly/server/block/cube" 5 "github.com/df-mc/dragonfly/server/block/model" 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/go-gl/mathgl/mgl64" 10 ) 11 12 // TODO: Dragon Heads can be powered by redstone 13 14 // Skull is a decorative block. There are seven types of skulls: player, zombie, skeleton, wither skeleton, creeper, 15 // dragon, and piglin. 16 type Skull struct { 17 transparent 18 sourceWaterDisplacer 19 20 // Type is the type of the skull. 21 Type SkullType 22 23 // Attach is the attachment of the Skull. It is either of the type WallAttachment or StandingAttachment. 24 //blockhash:facing_only 25 Attach Attachment 26 } 27 28 // Helmet ... 29 func (Skull) Helmet() bool { 30 return true 31 } 32 33 // DefencePoints ... 34 func (Skull) DefencePoints() float64 { 35 return 0 36 } 37 38 // Toughness ... 39 func (Skull) Toughness() float64 { 40 return 0 41 } 42 43 // KnockBackResistance ... 44 func (Skull) KnockBackResistance() float64 { 45 return 0 46 } 47 48 // Model ... 49 func (s Skull) Model() world.BlockModel { 50 return model.Skull{Direction: s.Attach.facing.Face(), Hanging: s.Attach.hanging} 51 } 52 53 // UseOnBlock ... 54 func (s Skull) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) (used bool) { 55 pos, face, used = firstReplaceable(w, pos, face, s) 56 if !used || face == cube.FaceDown { 57 return false 58 } 59 60 if face == cube.FaceUp { 61 s.Attach = StandingAttachment(user.Rotation().Orientation()) 62 } else { 63 s.Attach = WallAttachment(face.Direction()) 64 } 65 place(w, pos, s, user, ctx) 66 return placed(ctx) 67 } 68 69 // SideClosed ... 70 func (Skull) SideClosed(cube.Pos, cube.Pos, *world.World) bool { 71 return false 72 } 73 74 // HasLiquidDrops ... 75 func (Skull) HasLiquidDrops() bool { 76 return true 77 } 78 79 // BreakInfo ... 80 func (s Skull) BreakInfo() BreakInfo { 81 return newBreakInfo(1, alwaysHarvestable, nothingEffective, oneOf(Skull{Type: s.Type})) 82 } 83 84 // EncodeItem ... 85 func (s Skull) EncodeItem() (name string, meta int16) { 86 return "minecraft:skull", int16(s.Type.Uint8()) 87 } 88 89 // DecodeNBT ... 90 func (s Skull) DecodeNBT(data map[string]interface{}) interface{} { 91 s.Type = SkullType{skull(nbtconv.Uint8(data, "SkullType"))} 92 s.Attach.o = cube.Orientation(nbtconv.Uint8(data, "Rot")) 93 if s.Attach.facing >= 0 { 94 s.Attach.hanging = true 95 } 96 return s 97 } 98 99 // EncodeNBT ... 100 func (s Skull) EncodeNBT() map[string]interface{} { 101 return map[string]interface{}{"id": "Skull", "SkullType": s.Type.Uint8(), "Rot": byte(s.Attach.o)} 102 } 103 104 // EncodeBlock ... 105 func (s Skull) EncodeBlock() (string, map[string]interface{}) { 106 if s.Attach.hanging { 107 return "minecraft:skull", map[string]interface{}{"facing_direction": int32(s.Attach.facing) + 2} 108 } 109 return "minecraft:skull", map[string]interface{}{"facing_direction": int32(1)} 110 } 111 112 // allSkulls ... 113 func allSkulls() (skulls []world.Block) { 114 for _, f := range cube.HorizontalFaces() { 115 // A direction of -2 and -1 isn't actually valid, but when encoding the block these are encoded as 0 and 1. We 116 // can't otherwise represent this properly in an Attachment type. 117 skulls = append(skulls, Skull{Attach: WallAttachment(f.Direction())}) 118 } 119 return append(skulls, Skull{Attach: StandingAttachment(0)}) 120 }