Files
mc/server/block/cocoa_bean.go
TarnaWijaya 26ed99fda6
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
up3
2026-07-09 08:33:57 +08:00

128 lines
3.0 KiB
Go

package block
import (
"math/rand/v2"
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/block/model"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
)
// CocoaBean is a crop block found in jungle biomes.
type CocoaBean struct {
transparent
// Facing is the direction from the cocoa bean to the log.
Facing cube.Direction
// Age is the stage of the cocoa bean's growth. 2 is fully grown.
Age int
}
// BoneMeal ...
func (c CocoaBean) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
if c.Age == 2 {
return item.BoneMealResultNone
}
c.Age++
tx.SetBlock(pos, c, nil)
return item.BoneMealResultSmall
}
// HasLiquidDrops ...
func (c CocoaBean) HasLiquidDrops() bool {
return true
}
// NeighbourUpdateTick ...
func (c CocoaBean) NeighbourUpdateTick(pos, _ cube.Pos, tx *world.Tx) {
var woodType WoodType
switch b := tx.Block(pos.Side(c.Facing.Face())).(type) {
case Log:
woodType = b.Wood
case Wood:
woodType = b.Wood
}
if woodType != JungleWood() {
breakBlock(c, pos, tx)
}
}
// UseOnBlock ...
func (c CocoaBean) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *world.Tx, user item.User, ctx *item.UseContext) bool {
pos, _, used := firstReplaceable(tx, pos, face, c)
if !used {
return false
}
if face == cube.FaceUp || face == cube.FaceDown {
return false
}
var woodType WoodType
oppositePos := pos.Side(face.Opposite())
if log, ok := tx.Block(oppositePos).(Log); ok {
woodType = log.Wood
} else if wood, ok := tx.Block(oppositePos).(Wood); ok {
woodType = wood.Wood
}
if woodType == JungleWood() {
c.Facing = face.Opposite().Direction()
ctx.IgnoreBBox = true
place(tx, pos, c, user, ctx)
return placed(ctx)
}
return false
}
// RandomTick ...
func (c CocoaBean) RandomTick(pos cube.Pos, tx *world.Tx, r *rand.Rand) {
if c.Age < 2 && r.IntN(5) == 0 {
c.Age++
tx.SetBlock(pos, c, nil)
}
}
// BreakInfo ...
func (c CocoaBean) BreakInfo() BreakInfo {
return newBreakInfo(0.2, alwaysHarvestable, axeEffective, func(item.Tool, []item.Enchantment) []item.Stack {
if c.Age == 2 {
return []item.Stack{item.NewStack(c, rand.IntN(2)+2)}
}
return []item.Stack{item.NewStack(c, 1)}
}).withBlastResistance(15)
}
// CompostChance ...
func (CocoaBean) CompostChance() float64 {
return 0.65
}
// EncodeItem ...
func (c CocoaBean) EncodeItem() (name string, meta int16) {
return "minecraft:cocoa_beans", 0
}
// EncodeBlock ...
func (c CocoaBean) EncodeBlock() (name string, properties map[string]any) {
return "minecraft:cocoa", map[string]any{"age": int32(c.Age), "direction": int32(horizontalDirection(c.Facing))}
}
// Model ...
func (c CocoaBean) Model() world.BlockModel {
return model.CocoaBean{Facing: c.Facing, Age: c.Age}
}
// allCocoaBeans ...
func allCocoaBeans() (cocoa []world.Block) {
for i := cube.Direction(0); i <= 3; i++ {
cocoa = append(cocoa, CocoaBean{Facing: i, Age: 0})
cocoa = append(cocoa, CocoaBean{Facing: i, Age: 1})
cocoa = append(cocoa, CocoaBean{Facing: i, Age: 2})
}
return
}