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  }