github.com/df-mc/dragonfly@v0.9.13/server/block/melon_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 // MelonSeeds grow melon blocks. 13 type MelonSeeds struct { 14 crop 15 16 // direction is the direction from the stem to the melon. 17 Direction cube.Face 18 } 19 20 // SameCrop ... 21 func (MelonSeeds) SameCrop(c Crop) bool { 22 _, ok := c.(MelonSeeds) 23 return ok 24 } 25 26 // NeighbourUpdateTick ... 27 func (m MelonSeeds) 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: m}) 31 } else if m.Direction != cube.FaceDown { 32 if _, ok := w.Block(pos.Side(m.Direction)).(Melon); !ok { 33 m.Direction = cube.FaceDown 34 w.SetBlock(pos, m, nil) 35 } 36 } 37 } 38 39 // RandomTick ... 40 func (m MelonSeeds) RandomTick(pos cube.Pos, w *world.World, r *rand.Rand) { 41 if r.Float64() <= m.CalculateGrowthChance(pos, w) && w.Light(pos) >= 8 { 42 if m.Growth < 7 { 43 m.Growth++ 44 w.SetBlock(pos, m, nil) 45 } else { 46 directions := cube.Directions() 47 for _, i := range directions { 48 if _, ok := w.Block(pos.Side(i.Face())).(Melon); 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 m.Direction = direction 58 w.SetBlock(pos, m, nil) 59 w.SetBlock(stemPos, Melon{}, nil) 60 } 61 } 62 } 63 } 64 } 65 66 // BoneMeal ... 67 func (m MelonSeeds) BoneMeal(pos cube.Pos, w *world.World) bool { 68 if m.Growth == 7 { 69 return false 70 } 71 m.Growth = min(m.Growth+rand.Intn(4)+2, 7) 72 w.SetBlock(pos, m, nil) 73 return true 74 } 75 76 // UseOnBlock ... 77 func (m MelonSeeds) 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, m) 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, m, user, ctx) 88 return placed(ctx) 89 } 90 91 // BreakInfo ... 92 func (m MelonSeeds) BreakInfo() BreakInfo { 93 return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(m)) 94 } 95 96 // CompostChance ... 97 func (MelonSeeds) CompostChance() float64 { 98 return 0.3 99 } 100 101 // EncodeItem ... 102 func (m MelonSeeds) EncodeItem() (name string, meta int16) { 103 return "minecraft:melon_seeds", 0 104 } 105 106 // EncodeBlock ... 107 func (m MelonSeeds) EncodeBlock() (name string, properties map[string]any) { 108 return "minecraft:melon_stem", map[string]any{"facing_direction": int32(m.Direction), "growth": int32(m.Growth)} 109 } 110 111 // allMelonStems ... 112 func allMelonStems() (stems []world.Block) { 113 for i := 0; i <= 7; i++ { 114 for j := cube.Face(0); j <= 5; j++ { 115 stems = append(stems, MelonSeeds{crop: crop{Growth: i}, Direction: j}) 116 } 117 } 118 return 119 }