github.com/df-mc/dragonfly@v0.9.13/server/block/grindstone.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/item"
     7  	"github.com/df-mc/dragonfly/server/world"
     8  	"github.com/df-mc/dragonfly/server/world/particle"
     9  	"github.com/go-gl/mathgl/mgl64"
    10  )
    11  
    12  // Grindstone is a block that repairs items and tools as well as removing enchantments from them. It also serves as a
    13  // weaponsmith's job site block.
    14  type Grindstone struct {
    15  	transparent
    16  
    17  	// Attach represents the attachment type of the Grindstone.
    18  	Attach GrindstoneAttachment
    19  	// Facing represents the direction the Grindstone is facing.
    20  	Facing cube.Direction
    21  }
    22  
    23  // BreakInfo ...
    24  func (g Grindstone) BreakInfo() BreakInfo {
    25  	return newBreakInfo(2, pickaxeHarvestable, pickaxeEffective, oneOf(g)).withBlastResistance(30)
    26  }
    27  
    28  // Activate ...
    29  func (g Grindstone) Activate(pos cube.Pos, _ cube.Face, _ *world.World, u item.User, _ *item.UseContext) bool {
    30  	if opener, ok := u.(ContainerOpener); ok {
    31  		opener.OpenBlockContainer(pos)
    32  		return true
    33  	}
    34  	return false
    35  }
    36  
    37  // UseOnBlock ...
    38  func (g Grindstone) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) (used bool) {
    39  	pos, face, used = firstReplaceable(w, pos, face, g)
    40  	if !used {
    41  		return false
    42  	}
    43  	g.Facing = user.Rotation().Direction().Opposite()
    44  	if face == cube.FaceDown {
    45  		g.Attach = HangingGrindstoneAttachment()
    46  	} else if face != cube.FaceUp {
    47  		g.Attach = WallGrindstoneAttachment()
    48  		g.Facing = face.Direction()
    49  	}
    50  	place(w, pos, g, user, ctx)
    51  	return placed(ctx)
    52  }
    53  
    54  // NeighbourUpdateTick ...
    55  func (g Grindstone) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
    56  	supportFace := g.Facing.Face().Opposite()
    57  	if g.Attach == HangingGrindstoneAttachment() {
    58  		supportFace = cube.FaceUp
    59  	} else if g.Attach == StandingGrindstoneAttachment() {
    60  		supportFace = cube.FaceDown
    61  	}
    62  	if _, ok := w.Block(pos.Side(supportFace)).Model().(model.Solid); !ok {
    63  		w.SetBlock(pos, nil, nil)
    64  		w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: g})
    65  		dropItem(w, item.NewStack(g, 1), pos.Vec3Centre())
    66  	}
    67  }
    68  
    69  // Model ...
    70  func (g Grindstone) Model() world.BlockModel {
    71  	axis := cube.Y
    72  	if g.Attach == WallGrindstoneAttachment() {
    73  		axis = g.Facing.Face().Axis()
    74  	}
    75  	return model.Grindstone{Axis: axis}
    76  }
    77  
    78  // EncodeBlock ...
    79  func (g Grindstone) EncodeBlock() (string, map[string]any) {
    80  	return "minecraft:grindstone", map[string]any{
    81  		"attachment": g.Attach.String(),
    82  		"direction":  int32(horizontalDirection(g.Facing)),
    83  	}
    84  }
    85  
    86  // EncodeItem ...
    87  func (g Grindstone) EncodeItem() (name string, meta int16) {
    88  	return "minecraft:grindstone", 0
    89  }
    90  
    91  // allGrindstones ...
    92  func allGrindstones() (grindstones []world.Block) {
    93  	for _, a := range GrindstoneAttachments() {
    94  		for _, d := range cube.Directions() {
    95  			grindstones = append(grindstones, Grindstone{Attach: a, Facing: d})
    96  		}
    97  	}
    98  	return
    99  }