github.com/df-mc/dragonfly@v0.9.13/server/block/pumpkin_seeds.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 // PumpkinSeeds grow pumpkin blocks. 13 type PumpkinSeeds struct { 14 crop 15 16 // Direction is the direction from the stem to the pumpkin. 17 Direction cube.Face 18 } 19 20 // SameCrop ... 21 func (PumpkinSeeds) SameCrop(c Crop) bool { 22 _, ok := c.(PumpkinSeeds) 23 return ok 24 } 25 26 // NeighbourUpdateTick ... 27 func (p PumpkinSeeds) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) { 28 if _, ok := w.Block(pos.Side(cube.FaceDown)).(Farmland); !ok { 29 w.SetBlock(pos, nil, nil) 30 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: p}) 31 } else if p.Direction != cube.FaceDown { 32 if pumpkin, ok := w.Block(pos.Side(p.Direction)).(Pumpkin); !ok || pumpkin.Carved { 33 p.Direction = cube.FaceDown 34 w.SetBlock(pos, p, nil) 35 } 36 } 37 } 38 39 // RandomTick ... 40 func (p PumpkinSeeds) RandomTick(pos cube.Pos, w *world.World, r *rand.Rand) { 41 if r.Float64() <= p.CalculateGrowthChance(pos, w) && w.Light(pos) >= 8 { 42 if p.Growth < 7 { 43 p.Growth++ 44 w.SetBlock(pos, p, nil) 45 } else { 46 directions := []cube.Direction{cube.North, cube.South, cube.West, cube.East} 47 for _, i := range directions { 48 if _, ok := w.Block(pos.Side(i.Face())).(Pumpkin); ok { 49 return 50 } 51 } 52 direction := directions[r.Intn(len(directions))].Face() 53 stemPos := pos.Side(direction) 54 if _, ok := w.Block(stemPos).(Air); ok { 55 switch w.Block(stemPos.Side(cube.FaceDown)).(type) { 56 case Farmland, Dirt, Grass: 57 p.Direction = direction 58 w.SetBlock(pos, p, nil) 59 w.SetBlock(stemPos, Pumpkin{}, nil) 60 } 61 } 62 } 63 } 64 } 65 66 // BoneMeal ... 67 func (p PumpkinSeeds) BoneMeal(pos cube.Pos, w *world.World) bool { 68 if p.Growth == 7 { 69 return false 70 } 71 p.Growth = min(p.Growth+rand.Intn(4)+2, 7) 72 w.SetBlock(pos, p, nil) 73 return true 74 } 75 76 // UseOnBlock ... 77 func (p PumpkinSeeds) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 78 pos, _, used := firstReplaceable(w, pos, face, p) 79 if !used { 80 return false 81 } 82 83 if _, ok := w.Block(pos.Side(cube.FaceDown)).(Farmland); !ok { 84 return false 85 } 86 87 place(w, pos, p, user, ctx) 88 return placed(ctx) 89 } 90 91 // BreakInfo ... 92 func (p PumpkinSeeds) BreakInfo() BreakInfo { 93 return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(p)) 94 } 95 96 // CompostChance ... 97 func (PumpkinSeeds) CompostChance() float64 { 98 return 0.3 99 } 100 101 // EncodeItem ... 102 func (p PumpkinSeeds) EncodeItem() (name string, meta int16) { 103 return "minecraft:pumpkin_seeds", 0 104 } 105 106 // EncodeBlock ... 107 func (p PumpkinSeeds) EncodeBlock() (name string, properties map[string]any) { 108 return "minecraft:pumpkin_stem", map[string]any{"facing_direction": int32(p.Direction), "growth": int32(p.Growth)} 109 } 110 111 // allPumpkinStems 112 func allPumpkinStems() (stems []world.Block) { 113 for i := 0; i <= 7; i++ { 114 for j := cube.Face(0); j <= 5; j++ { 115 stems = append(stems, PumpkinSeeds{Direction: j, crop: crop{Growth: i}}) 116 } 117 } 118 return 119 }