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 }