github.com/df-mc/dragonfly@v0.9.13/server/block/tall_grass.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/df-mc/dragonfly/server/world/particle"
     8  	"github.com/go-gl/mathgl/mgl64"
     9  	"math/rand"
    10  )
    11  
    12  // TallGrass is a transparent plant block which can be used to obtain seeds and as decoration.
    13  type TallGrass struct {
    14  	replaceable
    15  	transparent
    16  	empty
    17  
    18  	// Type is the type of tall grass that the plant represents.
    19  	Type TallGrassType
    20  }
    21  
    22  // FlammabilityInfo ...
    23  func (g TallGrass) FlammabilityInfo() FlammabilityInfo {
    24  	return newFlammabilityInfo(60, 100, false)
    25  }
    26  
    27  // BreakInfo ...
    28  func (g TallGrass) BreakInfo() BreakInfo {
    29  	return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(t item.Tool, enchantments []item.Enchantment) []item.Stack {
    30  		if t.ToolType() == item.TypeShears || hasSilkTouch(enchantments) {
    31  			return []item.Stack{item.NewStack(g, 1)}
    32  		}
    33  		if rand.Float32() > 0.57 {
    34  			return []item.Stack{item.NewStack(WheatSeeds{}, 1)}
    35  		}
    36  		return nil
    37  	})
    38  }
    39  
    40  // BoneMeal attempts to affect the block using a bone meal item.
    41  func (g TallGrass) BoneMeal(pos cube.Pos, w *world.World) bool {
    42  	upper := DoubleTallGrass{Type: g.Type.Double(), UpperPart: true}
    43  	if replaceableWith(w, pos.Side(cube.FaceUp), upper) {
    44  		w.SetBlock(pos, DoubleTallGrass{Type: g.Type.Double()}, nil)
    45  		w.SetBlock(pos.Side(cube.FaceUp), upper, nil)
    46  		return true
    47  	}
    48  	return false
    49  }
    50  
    51  // CompostChance ...
    52  func (g TallGrass) CompostChance() float64 {
    53  	if g.Type == FernTallGrass() {
    54  		return 0.65
    55  	}
    56  	return 0.3
    57  }
    58  
    59  // NeighbourUpdateTick ...
    60  func (g TallGrass) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
    61  	if !supportsVegetation(g, w.Block(pos.Side(cube.FaceDown))) {
    62  		w.SetBlock(pos, nil, nil)
    63  		w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: g})
    64  	}
    65  }
    66  
    67  // HasLiquidDrops ...
    68  func (g TallGrass) HasLiquidDrops() bool {
    69  	return true
    70  }
    71  
    72  // UseOnBlock ...
    73  func (g TallGrass) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool {
    74  	pos, _, used := firstReplaceable(w, pos, face, g)
    75  	if !used {
    76  		return false
    77  	}
    78  	if !supportsVegetation(g, w.Block(pos.Side(cube.FaceDown))) {
    79  		return false
    80  	}
    81  
    82  	place(w, pos, g, user, ctx)
    83  	return placed(ctx)
    84  }
    85  
    86  // EncodeItem ...
    87  func (g TallGrass) EncodeItem() (name string, meta int16) {
    88  	return "minecraft:tallgrass", int16(g.Type.Uint8())
    89  }
    90  
    91  // EncodeBlock ...
    92  func (g TallGrass) EncodeBlock() (name string, properties map[string]any) {
    93  	return "minecraft:tallgrass", map[string]any{"tall_grass_type": g.Type.String()}
    94  }
    95  
    96  // allTallGrass ...
    97  func allTallGrass() (grasses []world.Block) {
    98  	for _, g := range TallGrassTypes() {
    99  		grasses = append(grasses, TallGrass{Type: g})
   100  	}
   101  	return
   102  }
   103  
   104  // supportsVegetation checks if the vegetation can exist on the block.
   105  func supportsVegetation(vegetation, block world.Block) bool {
   106  	soil, ok := block.(Soil)
   107  	return ok && soil.SoilFor(vegetation)
   108  }
   109  
   110  // Soil represents a block that can support vegetation.
   111  type Soil interface {
   112  	// SoilFor returns whether the vegetation can exist on the block.
   113  	SoilFor(world.Block) bool
   114  }