github.com/df-mc/dragonfly@v0.9.13/server/block/double_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 // DoubleTallGrass is a two-block high variety of grass. 13 type DoubleTallGrass struct { 14 transparent 15 replaceable 16 empty 17 18 // UpperPart is set if the plant is the upper part. 19 UpperPart bool 20 // Type is the type of double tall grass. 21 Type DoubleTallGrassType 22 } 23 24 // HasLiquidDrops ... 25 func (d DoubleTallGrass) HasLiquidDrops() bool { 26 return true 27 } 28 29 // NeighbourUpdateTick ... 30 func (d DoubleTallGrass) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) { 31 if d.UpperPart { 32 if bottom, ok := w.Block(pos.Side(cube.FaceDown)).(DoubleTallGrass); !ok || bottom.Type != d.Type || bottom.UpperPart { 33 w.SetBlock(pos, nil, nil) 34 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d}) 35 } 36 return 37 } 38 if upper, ok := w.Block(pos.Side(cube.FaceUp)).(DoubleTallGrass); !ok || upper.Type != d.Type || !upper.UpperPart { 39 w.SetBlock(pos, nil, nil) 40 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d}) 41 return 42 } 43 if !supportsVegetation(d, w.Block(pos.Side(cube.FaceDown))) { 44 w.SetBlock(pos, nil, nil) 45 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d}) 46 } 47 } 48 49 // UseOnBlock ... 50 func (d DoubleTallGrass) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 51 pos, _, used := firstReplaceable(w, pos, face, d) 52 if !used { 53 return false 54 } 55 if !replaceableWith(w, pos.Side(cube.FaceUp), d) { 56 return false 57 } 58 if !supportsVegetation(d, w.Block(pos.Side(cube.FaceDown))) { 59 return false 60 } 61 62 place(w, pos, d, user, ctx) 63 place(w, pos.Side(cube.FaceUp), DoubleTallGrass{Type: d.Type, UpperPart: true}, user, ctx) 64 return placed(ctx) 65 } 66 67 // FlammabilityInfo ... 68 func (d DoubleTallGrass) FlammabilityInfo() FlammabilityInfo { 69 return newFlammabilityInfo(60, 100, true) 70 } 71 72 // BreakInfo ... 73 func (d DoubleTallGrass) BreakInfo() BreakInfo { 74 return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(t item.Tool, enchantments []item.Enchantment) []item.Stack { 75 if t.ToolType() == item.TypeShears || hasSilkTouch(enchantments) { 76 return []item.Stack{item.NewStack(d, 1)} 77 } 78 if rand.Float32() > 0.57 { 79 return []item.Stack{item.NewStack(WheatSeeds{}, 1)} 80 } 81 return nil 82 }) 83 } 84 85 // CompostChance ... 86 func (d DoubleTallGrass) CompostChance() float64 { 87 if d.Type == FernDoubleTallGrass() { 88 return 0.65 89 } 90 return 0.5 91 } 92 93 // EncodeItem ... 94 func (d DoubleTallGrass) EncodeItem() (name string, meta int16) { 95 return "minecraft:double_plant", int16(d.Type.Uint8() + 2) 96 } 97 98 // EncodeBlock ... 99 func (d DoubleTallGrass) EncodeBlock() (string, map[string]any) { 100 return "minecraft:double_plant", map[string]any{"double_plant_type": d.Type.String(), "upper_block_bit": d.UpperPart} 101 } 102 103 // allDoubleTallGrass ... 104 func allDoubleTallGrass() (b []world.Block) { 105 for _, g := range DoubleTallGrassTypes() { 106 b = append(b, DoubleTallGrass{Type: g}) 107 b = append(b, DoubleTallGrass{Type: g, UpperPart: true}) 108 } 109 return 110 }