github.com/df-mc/dragonfly@v0.9.13/server/block/flower.go (about) 1 package block 2 3 import ( 4 "github.com/df-mc/dragonfly/server/block/cube" 5 "github.com/df-mc/dragonfly/server/entity/effect" 6 "github.com/df-mc/dragonfly/server/item" 7 "github.com/df-mc/dragonfly/server/world" 8 "github.com/df-mc/dragonfly/server/world/particle" 9 "github.com/go-gl/mathgl/mgl64" 10 "math/rand" 11 "time" 12 ) 13 14 // Flower is a non-solid plant that occur in a variety of shapes and colours. They are primarily used for decoration 15 // and crafted into dyes. 16 type Flower struct { 17 empty 18 transparent 19 20 // Type is the type of flower. 21 Type FlowerType 22 } 23 24 // EntityInside ... 25 func (f Flower) EntityInside(_ cube.Pos, _ *world.World, e world.Entity) { 26 if f.Type == WitherRose() { 27 if living, ok := e.(interface { 28 AddEffect(effect.Effect) 29 }); ok { 30 living.AddEffect(effect.New(effect.Wither{}, 1, 2*time.Second)) 31 } 32 } 33 } 34 35 // BoneMeal ... 36 func (f Flower) BoneMeal(pos cube.Pos, w *world.World) (success bool) { 37 if f.Type == WitherRose() { 38 return 39 } 40 41 for i := 0; i < 8; i++ { 42 p := pos.Add(cube.Pos{rand.Intn(7) - 3, rand.Intn(3) - 1, rand.Intn(7) - 3}) 43 if _, ok := w.Block(p).(Air); !ok { 44 continue 45 } 46 if _, ok := w.Block(p.Side(cube.FaceDown)).(Grass); !ok { 47 continue 48 } 49 flowerType := f.Type 50 if rand.Float64() < 0.1 { 51 if f.Type == Dandelion() { 52 flowerType = Poppy() 53 } else if f.Type == Poppy() { 54 flowerType = Dandelion() 55 } 56 } 57 w.SetBlock(p, Flower{Type: flowerType}, nil) 58 success = true 59 } 60 return 61 } 62 63 // NeighbourUpdateTick ... 64 func (f Flower) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) { 65 if !supportsVegetation(f, w.Block(pos.Side(cube.FaceDown))) { 66 w.SetBlock(pos, nil, nil) 67 w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: f}) 68 dropItem(w, item.NewStack(f, 1), pos.Vec3Centre()) 69 } 70 } 71 72 // UseOnBlock ... 73 func (f Flower) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool { 74 pos, _, used := firstReplaceable(w, pos, face, f) 75 if !used { 76 return false 77 } 78 if !supportsVegetation(f, w.Block(pos.Side(cube.FaceDown))) { 79 return false 80 } 81 82 place(w, pos, f, user, ctx) 83 return placed(ctx) 84 } 85 86 // HasLiquidDrops ... 87 func (Flower) HasLiquidDrops() bool { 88 return true 89 } 90 91 // FlammabilityInfo ... 92 func (f Flower) FlammabilityInfo() FlammabilityInfo { 93 return newFlammabilityInfo(60, 100, false) 94 } 95 96 // BreakInfo ... 97 func (f Flower) BreakInfo() BreakInfo { 98 return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(f)) 99 } 100 101 // CompostChance ... 102 func (Flower) CompostChance() float64 { 103 return 0.65 104 } 105 106 // EncodeItem ... 107 func (f Flower) EncodeItem() (name string, meta int16) { 108 if f.Type == Dandelion() { 109 return "minecraft:yellow_flower", 0 110 } else if f.Type == WitherRose() { 111 return "minecraft:wither_rose", 0 112 } 113 return "minecraft:red_flower", int16(f.Type.Uint8() - 1) 114 } 115 116 // EncodeBlock ... 117 func (f Flower) EncodeBlock() (string, map[string]any) { 118 if f.Type == Dandelion() { 119 return "minecraft:yellow_flower", nil 120 } else if f.Type == WitherRose() { 121 return "minecraft:wither_rose", nil 122 } 123 return "minecraft:red_flower", map[string]any{"flower_type": f.Type.String()} 124 } 125 126 // allFlowers ... 127 func allFlowers() (b []world.Block) { 128 for _, f := range FlowerTypes() { 129 b = append(b, Flower{Type: f}) 130 } 131 return 132 }