github.com/df-mc/dragonfly@v0.9.13/server/block/composter.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/df-mc/dragonfly/server/world/particle" 9 "github.com/df-mc/dragonfly/server/world/sound" 10 "math/rand" 11 "time" 12 ) 13 14 // Composter is a block that can turn biological matter in to compost which can then produce bone meal. It is also the 15 // work station for a farming villager. 16 type Composter struct { 17 bass 18 transparent 19 sourceWaterDisplacer 20 21 // Level is the level of compost inside the composter. At level 8 it can be collected in the form of bone meal. 22 Level int 23 } 24 25 // Model ... 26 func (c Composter) Model() world.BlockModel { 27 return model.Composter{Level: c.Level} 28 } 29 30 // FuelInfo ... 31 func (c Composter) FuelInfo() item.FuelInfo { 32 return newFuelInfo(time.Second * 15) 33 } 34 35 // FlammabilityInfo ... 36 func (c Composter) FlammabilityInfo() FlammabilityInfo { 37 return newFlammabilityInfo(5, 20, true) 38 } 39 40 // SideClosed ... 41 func (c Composter) SideClosed(cube.Pos, cube.Pos, *world.World) bool { 42 return false 43 } 44 45 // BreakInfo ... 46 func (c Composter) BreakInfo() BreakInfo { 47 return newBreakInfo(2, alwaysHarvestable, axeEffective, oneOf(c)).withBreakHandler(func(pos cube.Pos, w *world.World, u item.User) { 48 if c.Level == 8 { 49 dropItem(w, item.NewStack(item.BoneMeal{}, 1), pos.Side(cube.FaceUp).Vec3Middle()) 50 } 51 }) 52 } 53 54 // Activate ... 55 func (c Composter) Activate(pos cube.Pos, _ cube.Face, w *world.World, u item.User, ctx *item.UseContext) bool { 56 if c.Level >= 7 { 57 if c.Level == 8 { 58 c.Level = 0 59 w.SetBlock(pos, c, nil) 60 dropItem(w, item.NewStack(item.BoneMeal{}, 1), pos.Side(cube.FaceUp).Vec3Middle()) 61 w.PlaySound(pos.Vec3(), sound.ComposterEmpty{}) 62 } 63 return false 64 } 65 it, _ := u.HeldItems() 66 compostable, ok := it.Item().(item.Compostable) 67 if !ok { 68 return false 69 } 70 ctx.SubtractFromCount(1) 71 w.AddParticle(pos.Vec3(), particle.BoneMeal{}) 72 if rand.Float64() > compostable.CompostChance() { 73 w.PlaySound(pos.Vec3(), sound.ComposterFill{}) 74 return true 75 } 76 c.Level++ 77 w.SetBlock(pos, c, nil) 78 w.PlaySound(pos.Vec3(), sound.ComposterFillLayer{}) 79 if c.Level == 7 { 80 w.ScheduleBlockUpdate(pos, time.Second) 81 } 82 return true 83 } 84 85 // ScheduledTick ... 86 func (c Composter) ScheduledTick(pos cube.Pos, w *world.World, _ *rand.Rand) { 87 if c.Level == 7 { 88 c.Level = 8 89 w.SetBlock(pos, c, nil) 90 w.PlaySound(pos.Vec3(), sound.ComposterReady{}) 91 } 92 } 93 94 // EncodeItem ... 95 func (c Composter) EncodeItem() (name string, meta int16) { 96 return "minecraft:composter", 0 97 } 98 99 // EncodeBlock ... 100 func (c Composter) EncodeBlock() (string, map[string]any) { 101 return "minecraft:composter", map[string]any{"composter_fill_level": int32(c.Level)} 102 } 103 104 // allComposters ... 105 func allComposters() (all []world.Block) { 106 for i := 0; i < 9; i++ { 107 all = append(all, Composter{Level: i}) 108 } 109 return 110 }