github.com/df-mc/dragonfly@v0.9.13/server/block/lantern.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/go-gl/mathgl/mgl64" 9 ) 10 11 // Lantern is a light emitting block. 12 type Lantern struct { 13 transparent 14 sourceWaterDisplacer 15 16 // Hanging determines if a lantern is hanging off a block. 17 Hanging bool 18 // Type of fire lighting the lantern. 19 Type FireType 20 } 21 22 // Model ... 23 func (l Lantern) Model() world.BlockModel { 24 return model.Lantern{Hanging: l.Hanging} 25 } 26 27 // NeighbourUpdateTick ... 28 func (l Lantern) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) { 29 if l.Hanging { 30 up := pos.Side(cube.FaceUp) 31 if _, ok := w.Block(up).(Chain); !ok && !w.Block(up).Model().FaceSolid(up, cube.FaceDown, w) { 32 w.SetBlock(pos, nil, nil) 33 dropItem(w, item.NewStack(l, 1), pos.Vec3Centre()) 34 } 35 } else { 36 down := pos.Side(cube.FaceDown) 37 if !w.Block(down).Model().FaceSolid(down, cube.FaceUp, w) { 38 w.SetBlock(pos, nil, nil) 39 dropItem(w, item.NewStack(l, 1), pos.Vec3Centre()) 40 } 41 } 42 } 43 44 // LightEmissionLevel ... 45 func (l Lantern) LightEmissionLevel() uint8 { 46 return l.Type.LightLevel() 47 } 48 49 // UseOnBlock ... 50 func (l Lantern) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 51 pos, face, used := firstReplaceable(w, pos, face, l) 52 if !used { 53 return false 54 } 55 if face == cube.FaceDown { 56 upPos := pos.Side(cube.FaceUp) 57 if _, ok := w.Block(upPos).(Chain); !ok && !w.Block(upPos).Model().FaceSolid(upPos, cube.FaceDown, w) { 58 face = cube.FaceUp 59 } 60 } 61 if face != cube.FaceDown { 62 downPos := pos.Side(cube.FaceDown) 63 if !w.Block(downPos).Model().FaceSolid(downPos, cube.FaceUp, w) { 64 return false 65 } 66 } 67 l.Hanging = face == cube.FaceDown 68 69 place(w, pos, l, user, ctx) 70 return placed(ctx) 71 } 72 73 // SideClosed ... 74 func (l Lantern) SideClosed(cube.Pos, cube.Pos, *world.World) bool { 75 return false 76 } 77 78 // BreakInfo ... 79 func (l Lantern) BreakInfo() BreakInfo { 80 return newBreakInfo(5, pickaxeHarvestable, pickaxeEffective, oneOf(l)) 81 } 82 83 // EncodeItem ... 84 func (l Lantern) EncodeItem() (name string, meta int16) { 85 switch l.Type { 86 case NormalFire(): 87 return "minecraft:lantern", 0 88 case SoulFire(): 89 return "minecraft:soul_lantern", 0 90 } 91 panic("invalid fire type") 92 } 93 94 // EncodeBlock ... 95 func (l Lantern) EncodeBlock() (name string, properties map[string]any) { 96 switch l.Type { 97 case NormalFire(): 98 return "minecraft:lantern", map[string]any{"hanging": l.Hanging} 99 case SoulFire(): 100 return "minecraft:soul_lantern", map[string]any{"hanging": l.Hanging} 101 } 102 panic("invalid fire type") 103 } 104 105 // allLanterns ... 106 func allLanterns() (lanterns []world.Block) { 107 for _, f := range FireTypes() { 108 lanterns = append(lanterns, Lantern{Hanging: false, Type: f}) 109 lanterns = append(lanterns, Lantern{Hanging: true, Type: f}) 110 } 111 return 112 }