github.com/df-mc/dragonfly@v0.9.13/server/block/cocoa_bean.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 "math/rand" 10 ) 11 12 // CocoaBean is a crop block found in jungle biomes. 13 type CocoaBean struct { 14 transparent 15 16 // Facing is the direction from the cocoa bean to the log. 17 Facing cube.Direction 18 // Age is the stage of the cocoa bean's growth. 2 is fully grown. 19 Age int 20 } 21 22 // BoneMeal ... 23 func (c CocoaBean) BoneMeal(pos cube.Pos, w *world.World) bool { 24 if c.Age == 2 { 25 return false 26 } 27 c.Age++ 28 w.SetBlock(pos, c, nil) 29 return true 30 } 31 32 // HasLiquidDrops ... 33 func (c CocoaBean) HasLiquidDrops() bool { 34 return true 35 } 36 37 // NeighbourUpdateTick ... 38 func (c CocoaBean) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) { 39 var woodType WoodType 40 switch b := w.Block(pos.Side(c.Facing.Face())).(type) { 41 case Log: 42 woodType = b.Wood 43 case Wood: 44 woodType = b.Wood 45 } 46 if woodType != JungleWood() { 47 w.SetBlock(pos, nil, nil) 48 } 49 } 50 51 // UseOnBlock ... 52 func (c CocoaBean) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 53 pos, _, used := firstReplaceable(w, pos, face, c) 54 if !used { 55 return false 56 } 57 58 if face == cube.FaceUp || face == cube.FaceDown { 59 return false 60 } 61 62 var woodType WoodType 63 oppositePos := pos.Side(face.Opposite()) 64 if log, ok := w.Block(oppositePos).(Log); ok { 65 woodType = log.Wood 66 } else if wood, ok := w.Block(oppositePos).(Wood); ok { 67 woodType = wood.Wood 68 } 69 if woodType == JungleWood() { 70 c.Facing = face.Opposite().Direction() 71 ctx.IgnoreBBox = true 72 73 place(w, pos, c, user, ctx) 74 return placed(ctx) 75 } 76 77 return false 78 } 79 80 // RandomTick ... 81 func (c CocoaBean) RandomTick(pos cube.Pos, w *world.World, r *rand.Rand) { 82 if c.Age < 2 && r.Intn(5) == 0 { 83 c.Age++ 84 w.SetBlock(pos, c, nil) 85 } 86 } 87 88 // BreakInfo ... 89 func (c CocoaBean) BreakInfo() BreakInfo { 90 return newBreakInfo(0.2, alwaysHarvestable, axeEffective, func(item.Tool, []item.Enchantment) []item.Stack { 91 if c.Age == 2 { 92 return []item.Stack{item.NewStack(c, rand.Intn(2)+2)} 93 } 94 return []item.Stack{item.NewStack(c, 1)} 95 }).withBlastResistance(15) 96 } 97 98 // CompostChance ... 99 func (CocoaBean) CompostChance() float64 { 100 return 0.65 101 } 102 103 // EncodeItem ... 104 func (c CocoaBean) EncodeItem() (name string, meta int16) { 105 return "minecraft:cocoa_beans", 0 106 } 107 108 // EncodeBlock ... 109 func (c CocoaBean) EncodeBlock() (name string, properties map[string]any) { 110 return "minecraft:cocoa", map[string]any{"age": int32(c.Age), "direction": int32(horizontalDirection(c.Facing))} 111 } 112 113 // Model ... 114 func (c CocoaBean) Model() world.BlockModel { 115 return model.CocoaBean{Facing: c.Facing, Age: c.Age} 116 } 117 118 // allCocoaBeans ... 119 func allCocoaBeans() (cocoa []world.Block) { 120 for i := cube.Direction(0); i <= 3; i++ { 121 cocoa = append(cocoa, CocoaBean{Facing: i, Age: 0}) 122 cocoa = append(cocoa, CocoaBean{Facing: i, Age: 1}) 123 cocoa = append(cocoa, CocoaBean{Facing: i, Age: 2}) 124 } 125 return 126 }