github.com/df-mc/dragonfly@v0.9.13/server/block/carrot.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 "time" 11 ) 12 13 // Carrot is a crop that can be consumed raw. 14 type Carrot struct { 15 crop 16 } 17 18 // SameCrop ... 19 func (Carrot) SameCrop(c Crop) bool { 20 _, ok := c.(Carrot) 21 return ok 22 } 23 24 // AlwaysConsumable ... 25 func (c Carrot) AlwaysConsumable() bool { 26 return false 27 } 28 29 // ConsumeDuration ... 30 func (c Carrot) ConsumeDuration() time.Duration { 31 return item.DefaultConsumeDuration 32 } 33 34 // Consume ... 35 func (c Carrot) Consume(_ *world.World, consumer item.Consumer) item.Stack { 36 consumer.Saturate(3, 3.6) 37 return item.Stack{} 38 } 39 40 // BoneMeal ... 41 func (c Carrot) BoneMeal(pos cube.Pos, w *world.World) bool { 42 if c.Growth == 7 { 43 return false 44 } 45 c.Growth = min(c.Growth+rand.Intn(4)+2, 7) 46 w.SetBlock(pos, c, nil) 47 return true 48 } 49 50 // UseOnBlock ... 51 func (c Carrot) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 52 pos, _, used := firstReplaceable(w, pos, face, c) 53 if !used { 54 return false 55 } 56 57 if _, ok := w.Block(pos.Side(cube.FaceDown)).(Farmland); !ok { 58 return false 59 } 60 61 place(w, pos, c, user, ctx) 62 return placed(ctx) 63 } 64 65 // BreakInfo ... 66 func (c Carrot) BreakInfo() BreakInfo { 67 return newBreakInfo(0, alwaysHarvestable, nothingEffective, func(item.Tool, []item.Enchantment) []item.Stack { 68 if c.Growth < 7 { 69 return []item.Stack{item.NewStack(c, 1)} 70 } 71 return []item.Stack{item.NewStack(c, rand.Intn(4)+2)} 72 }) 73 } 74 75 // CompostChance ... 76 func (Carrot) CompostChance() float64 { 77 return 0.65 78 } 79 80 // EncodeItem ... 81 func (c Carrot) EncodeItem() (name string, meta int16) { 82 return "minecraft:carrot", 0 83 } 84 85 // RandomTick ... 86 func (c Carrot) RandomTick(pos cube.Pos, w *world.World, r *rand.Rand) { 87 if w.Light(pos) < 8 { 88 w.SetBlock(pos, nil, nil) 89 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: c}) 90 } else if c.Growth < 7 && r.Float64() <= c.CalculateGrowthChance(pos, w) { 91 c.Growth++ 92 w.SetBlock(pos, c, nil) 93 } 94 } 95 96 // EncodeBlock ... 97 func (c Carrot) EncodeBlock() (name string, properties map[string]any) { 98 return "minecraft:carrots", map[string]any{"growth": int32(c.Growth)} 99 } 100 101 // allCarrots ... 102 func allCarrots() (carrots []world.Block) { 103 for growth := 0; growth < 8; growth++ { 104 carrots = append(carrots, Carrot{crop{Growth: growth}}) 105 } 106 return 107 }