Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions server/block/hanging_roots.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
"github.com/go-gl/mathgl/mgl64"
)

// HangingRoots is a decorative block that hangs from the underside of blocks in lush caves.
type HangingRoots struct {
empty
replaceable
transparent
sourceWaterDisplacer
}

// NeighbourUpdateTick ...
func (h HangingRoots) NeighbourUpdateTick(pos, _ cube.Pos, tx *world.Tx) {
if up := pos.Side(cube.FaceUp); !tx.Block(up).Model().FaceSolid(up, cube.FaceDown, tx) {
breakBlock(h, pos, tx)
}
}

// UseOnBlock ...
func (h HangingRoots) 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, h)
if !used {
return false
}
if up := pos.Side(cube.FaceUp); !tx.Block(up).Model().FaceSolid(up, cube.FaceDown, tx) {
return false
}

place(tx, pos, h, user, ctx)
return placed(ctx)
}

// SideClosed ...
func (HangingRoots) SideClosed(cube.Pos, cube.Pos, *world.Tx) bool {
return false
}

// HasLiquidDrops ...
func (HangingRoots) HasLiquidDrops() bool {
return true
}

// FlammabilityInfo ...
func (HangingRoots) FlammabilityInfo() FlammabilityInfo {
return newFlammabilityInfo(15, 100, true)
}

// CompostChance ...
func (HangingRoots) CompostChance() float64 {
return 0.3
}

// BreakInfo ...
func (h HangingRoots) BreakInfo() BreakInfo {
return newBreakInfo(0, alwaysHarvestable, shearsEffective, func(t item.Tool, enchantments []item.Enchantment) []item.Stack {
if t.ToolType() == item.TypeShears || hasSilkTouch(enchantments) {
return []item.Stack{item.NewStack(h, 1)}
}
return nil
})
}

// EncodeItem ...
func (HangingRoots) EncodeItem() (name string, meta int16) {
return "minecraft:hanging_roots", 0
}

// EncodeBlock ...
func (HangingRoots) EncodeBlock() (string, map[string]any) {
return "minecraft:hanging_roots", nil
}
10 changes: 10 additions & 0 deletions server/block/hash.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions server/block/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func init() {
world.RegisterBlock(Granite{})
world.RegisterBlock(Grass{})
world.RegisterBlock(Gravel{})
world.RegisterBlock(HangingRoots{})
world.RegisterBlock(Honeycomb{})
world.RegisterBlock(InfestedStone{})
world.RegisterBlock(InfestedCobblestone{})
Expand Down Expand Up @@ -113,6 +114,7 @@ func init() {
world.RegisterBlock(ResinBricks{Chiseled: true})
world.RegisterBlock(ResinBricks{})
world.RegisterBlock(Resin{})
world.RegisterBlock(RootedDirt{})
world.RegisterBlock(Sand{Red: true})
world.RegisterBlock(Sand{})
world.RegisterBlock(SeaLantern{})
Expand Down Expand Up @@ -336,6 +338,7 @@ func init() {
world.RegisterItem(Grass{})
world.RegisterItem(Gravel{})
world.RegisterItem(Grindstone{})
world.RegisterItem(HangingRoots{})
world.RegisterItem(HayBale{})
world.RegisterItem(Honeycomb{})
world.RegisterItem(Hopper{})
Expand Down Expand Up @@ -404,6 +407,7 @@ func init() {
world.RegisterItem(ResinBricks{Chiseled: true})
world.RegisterItem(ResinBricks{})
world.RegisterItem(Resin{})
world.RegisterItem(RootedDirt{})
world.RegisterItem(Sand{Red: true})
world.RegisterItem(Sand{})
world.RegisterItem(SeaLantern{})
Expand Down
61 changes: 61 additions & 0 deletions server/block/rooted_dirt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package block

import (
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/item"
"github.com/df-mc/dragonfly/server/world"
)

// RootedDirt is a variant of dirt that generates in lush caves underneath azalea trees.
type RootedDirt struct {
solid
}

// SoilFor ...
func (r RootedDirt) SoilFor(block world.Block) bool {
switch block.(type) {
case ShortGrass, Fern, DoubleTallGrass, Flower, DoubleFlower, NetherSprouts, PinkPetals, SugarCane, DeadBush, BambooSapling, Bamboo:
return true
}
return false
}

// BoneMeal ...
func (r RootedDirt) BoneMeal(pos cube.Pos, tx *world.Tx) item.BoneMealResult {
below := pos.Side(cube.FaceDown)
if _, ok := tx.Block(below).(Air); !ok {
return item.BoneMealResultNone
}
tx.SetBlock(below, HangingRoots{}, nil)
return item.BoneMealResultSmall
}

// Till returns dirt, as using a hoe on rooted dirt strips its roots instead of tilling it into farmland.
func (RootedDirt) Till() (world.Block, bool) {
return Dirt{}, true
}

// TillDrops ...
func (RootedDirt) TillDrops() []item.Stack {
return []item.Stack{item.NewStack(HangingRoots{}, 1)}
}

// Shovel ...
func (RootedDirt) Shovel() (world.Block, bool) {
return DirtPath{}, true
}

// BreakInfo ...
func (r RootedDirt) BreakInfo() BreakInfo {
return newBreakInfo(0.5, alwaysHarvestable, shovelEffective, oneOf(r))
}

// EncodeItem ...
func (RootedDirt) EncodeItem() (name string, meta int16) {
return "minecraft:dirt_with_roots", 0
}

// EncodeBlock ...
func (RootedDirt) EncodeBlock() (string, map[string]any) {
return "minecraft:dirt_with_roots", nil
}
16 changes: 16 additions & 0 deletions server/item/hoe.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ func (h Hoe) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, tx *world.Tx
}
tx.SetBlock(pos, res, nil)
tx.PlaySound(pos.Vec3(), sound.ItemUseOn{Block: res})
if d, ok := b.(tillDropper); ok {
dir := pos.Side(face).Vec3().Sub(pos.Vec3())
vel := dir.Mul(0.1)
vel[1] += 0.1
create := tx.World().EntityRegistry().Config().Item
for _, drop := range d.TillDrops() {
opts := world.EntitySpawnOpts{Position: pos.Vec3Centre().Add(dir.Mul(0.625)), Velocity: vel}
tx.AddEntity(create(opts, drop))
}
}
ctx.DamageItem(1)
return true
}
Expand All @@ -42,6 +52,12 @@ type tillable interface {
Till() (world.Block, bool)
}

// tillDropper represents a block that drops items when a hoe is used on it.
type tillDropper interface {
// TillDrops returns the items dropped when a hoe is used on the block.
TillDrops() []Stack
}

// MaxCount ...
func (h Hoe) MaxCount() int {
return 1
Expand Down