github.com/df-mc/dragonfly@v0.9.13/server/block/torch.go (about)

     1  package block
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/block/cube"
     5  	"github.com/df-mc/dragonfly/server/item"
     6  	"github.com/df-mc/dragonfly/server/world"
     7  	"github.com/go-gl/mathgl/mgl64"
     8  )
     9  
    10  // Torch are non-solid blocks that emit light.
    11  type Torch struct {
    12  	transparent
    13  	empty
    14  
    15  	// Facing is the direction from the torch to the block.
    16  	Facing cube.Face
    17  	// Type is the type of fire lighting the torch.
    18  	Type FireType
    19  }
    20  
    21  // BreakInfo ...
    22  func (t Torch) BreakInfo() BreakInfo {
    23  	return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(t))
    24  }
    25  
    26  // LightEmissionLevel ...
    27  func (t Torch) LightEmissionLevel() uint8 {
    28  	switch t.Type {
    29  	case NormalFire():
    30  		return 14
    31  	default:
    32  		return t.Type.LightLevel()
    33  	}
    34  }
    35  
    36  // UseOnBlock ...
    37  func (t Torch) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool {
    38  	pos, face, used := firstReplaceable(w, pos, face, t)
    39  	if !used {
    40  		return false
    41  	}
    42  	if face == cube.FaceDown {
    43  		return false
    44  	}
    45  	if _, ok := w.Block(pos).(world.Liquid); ok {
    46  		return false
    47  	}
    48  	if !w.Block(pos.Side(face.Opposite())).Model().FaceSolid(pos.Side(face.Opposite()), face, w) {
    49  		found := false
    50  		for _, i := range []cube.Face{cube.FaceSouth, cube.FaceWest, cube.FaceNorth, cube.FaceEast, cube.FaceDown} {
    51  			if w.Block(pos.Side(i)).Model().FaceSolid(pos.Side(i), i.Opposite(), w) {
    52  				found = true
    53  				face = i.Opposite()
    54  				break
    55  			}
    56  		}
    57  		if !found {
    58  			return false
    59  		}
    60  	}
    61  	t.Facing = face.Opposite()
    62  
    63  	place(w, pos, t, user, ctx)
    64  	return placed(ctx)
    65  }
    66  
    67  // NeighbourUpdateTick ...
    68  func (t Torch) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
    69  	if !w.Block(pos.Side(t.Facing)).Model().FaceSolid(pos.Side(t.Facing), t.Facing.Opposite(), w) {
    70  		w.SetBlock(pos, nil, nil)
    71  		dropItem(w, item.NewStack(t, 1), pos.Vec3Centre())
    72  	}
    73  }
    74  
    75  // HasLiquidDrops ...
    76  func (t Torch) HasLiquidDrops() bool {
    77  	return true
    78  }
    79  
    80  // EncodeItem ...
    81  func (t Torch) EncodeItem() (name string, meta int16) {
    82  	switch t.Type {
    83  	case NormalFire():
    84  		return "minecraft:torch", 0
    85  	case SoulFire():
    86  		return "minecraft:soul_torch", 0
    87  	}
    88  	panic("invalid fire type")
    89  }
    90  
    91  // EncodeBlock ...
    92  func (t Torch) EncodeBlock() (name string, properties map[string]any) {
    93  	face := t.Facing.String()
    94  	if t.Facing == cube.FaceDown {
    95  		face = "top"
    96  	}
    97  	switch t.Type {
    98  	case NormalFire():
    99  		return "minecraft:torch", map[string]any{"torch_facing_direction": face}
   100  	case SoulFire():
   101  		return "minecraft:soul_torch", map[string]any{"torch_facing_direction": face}
   102  	}
   103  	panic("invalid fire type")
   104  }
   105  
   106  // allTorches ...
   107  func allTorches() (torch []world.Block) {
   108  	for i := cube.Face(0); i < 6; i++ {
   109  		if i == cube.FaceUp {
   110  			continue
   111  		}
   112  		torch = append(torch, Torch{Type: NormalFire(), Facing: i})
   113  		torch = append(torch, Torch{Type: SoulFire(), Facing: i})
   114  	}
   115  	return
   116  }