github.com/df-mc/dragonfly@v0.9.13/server/block/ladder.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  	"time"
    11  )
    12  
    13  // Ladder is a wooden block used for climbing walls either vertically or horizontally. They can be placed only on
    14  // the sides of other blocks.
    15  type Ladder struct {
    16  	transparent
    17  	sourceWaterDisplacer
    18  
    19  	// Facing is the side of the block the ladder is currently attached to.
    20  	Facing cube.Direction
    21  }
    22  
    23  // NeighbourUpdateTick ...
    24  func (l Ladder) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
    25  	if _, ok := w.Block(pos.Side(l.Facing.Opposite().Face())).(LightDiffuser); ok {
    26  		w.SetBlock(pos, nil, nil)
    27  		w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: l})
    28  		dropItem(w, item.NewStack(l, 1), pos.Vec3Centre())
    29  	}
    30  }
    31  
    32  // UseOnBlock ...
    33  func (l Ladder) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool {
    34  	pos, face, used := firstReplaceable(w, pos, face, l)
    35  	if !used {
    36  		return false
    37  	}
    38  	if face == cube.FaceUp || face == cube.FaceDown {
    39  		return false
    40  	}
    41  	if _, ok := w.Block(pos.Side(face.Opposite())).(LightDiffuser); ok {
    42  		found := false
    43  		for _, i := range []cube.Face{cube.FaceSouth, cube.FaceNorth, cube.FaceEast, cube.FaceWest} {
    44  			if diffuser, ok := w.Block(pos.Side(i)).(LightDiffuser); !ok || diffuser.LightDiffusionLevel() == 15 {
    45  				found = true
    46  				face = i.Opposite()
    47  				break
    48  			}
    49  		}
    50  		if !found {
    51  			return false
    52  		}
    53  	}
    54  	l.Facing = face.Direction()
    55  
    56  	place(w, pos, l, user, ctx)
    57  	return placed(ctx)
    58  }
    59  
    60  // EntityInside ...
    61  func (l Ladder) EntityInside(_ cube.Pos, _ *world.World, e world.Entity) {
    62  	if fallEntity, ok := e.(fallDistanceEntity); ok {
    63  		fallEntity.ResetFallDistance()
    64  	}
    65  }
    66  
    67  // SideClosed ...
    68  func (l Ladder) SideClosed(cube.Pos, cube.Pos, *world.World) bool {
    69  	return false
    70  }
    71  
    72  // BreakInfo ...
    73  func (l Ladder) BreakInfo() BreakInfo {
    74  	return newBreakInfo(0.4, alwaysHarvestable, axeEffective, oneOf(l))
    75  }
    76  
    77  // FuelInfo ...
    78  func (Ladder) FuelInfo() item.FuelInfo {
    79  	return newFuelInfo(time.Second * 15)
    80  }
    81  
    82  // EncodeItem ...
    83  func (l Ladder) EncodeItem() (name string, meta int16) {
    84  	return "minecraft:ladder", 0
    85  }
    86  
    87  // EncodeBlock ...
    88  func (l Ladder) EncodeBlock() (string, map[string]any) {
    89  	return "minecraft:ladder", map[string]any{"facing_direction": int32(l.Facing + 2)}
    90  }
    91  
    92  // Model ...
    93  func (l Ladder) Model() world.BlockModel {
    94  	return model.Ladder{Facing: l.Facing}
    95  }
    96  
    97  // allLadders ...
    98  func allLadders() (b []world.Block) {
    99  	for i := cube.Direction(0); i <= 3; i++ {
   100  		b = append(b, Ladder{Facing: i})
   101  	}
   102  	return
   103  }