github.com/df-mc/dragonfly@v0.9.13/server/block/double_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/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  )
    10  
    11  // DoubleFlower is a two block high flower consisting of an upper and lower part.
    12  type DoubleFlower struct {
    13  	transparent
    14  	empty
    15  
    16  	// UpperPart is set if the plant is the upper part.
    17  	UpperPart bool
    18  	// Type is the type of the double plant.
    19  	Type DoubleFlowerType
    20  }
    21  
    22  // FlammabilityInfo ...
    23  func (d DoubleFlower) FlammabilityInfo() FlammabilityInfo {
    24  	return newFlammabilityInfo(60, 100, true)
    25  }
    26  
    27  // BoneMeal ...
    28  func (d DoubleFlower) BoneMeal(pos cube.Pos, w *world.World) bool {
    29  	dropItem(w, item.NewStack(d, 1), pos.Vec3Centre())
    30  	return true
    31  }
    32  
    33  // NeighbourUpdateTick ...
    34  func (d DoubleFlower) NeighbourUpdateTick(pos, _ cube.Pos, w *world.World) {
    35  	if d.UpperPart {
    36  		if bottom, ok := w.Block(pos.Side(cube.FaceDown)).(DoubleFlower); !ok || bottom.Type != d.Type || bottom.UpperPart {
    37  			w.SetBlock(pos, nil, nil)
    38  			w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d})
    39  			dropItem(w, item.NewStack(d, 1), pos.Vec3Middle())
    40  		}
    41  		return
    42  	}
    43  	if upper, ok := w.Block(pos.Side(cube.FaceUp)).(DoubleFlower); !ok || upper.Type != d.Type || !upper.UpperPart {
    44  		w.SetBlock(pos, nil, nil)
    45  		w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d})
    46  		return
    47  	}
    48  	if !supportsVegetation(d, w.Block(pos.Side(cube.FaceDown))) {
    49  		w.SetBlock(pos, nil, nil)
    50  		w.AddParticle(pos.Vec3Centre(), particle.BlockBreak{Block: d})
    51  	}
    52  }
    53  
    54  // UseOnBlock ...
    55  func (d DoubleFlower) UseOnBlock(pos cube.Pos, face cube.Face, _ mgl64.Vec3, w *world.World, user item.User, ctx *item.UseContext) bool {
    56  	pos, _, used := firstReplaceable(w, pos, face, d)
    57  	if !used {
    58  		return false
    59  	}
    60  	if !replaceableWith(w, pos.Side(cube.FaceUp), d) {
    61  		return false
    62  	}
    63  	if !supportsVegetation(d, w.Block(pos.Side(cube.FaceDown))) {
    64  		return false
    65  	}
    66  
    67  	place(w, pos, d, user, ctx)
    68  	place(w, pos.Side(cube.FaceUp), DoubleFlower{Type: d.Type, UpperPart: true}, user, ctx)
    69  	return placed(ctx)
    70  }
    71  
    72  // BreakInfo ...
    73  func (d DoubleFlower) BreakInfo() BreakInfo {
    74  	return newBreakInfo(0, alwaysHarvestable, nothingEffective, oneOf(d))
    75  }
    76  
    77  // CompostChance ...
    78  func (DoubleFlower) CompostChance() float64 {
    79  	return 0.65
    80  }
    81  
    82  // HasLiquidDrops ...
    83  func (d DoubleFlower) HasLiquidDrops() bool {
    84  	return true
    85  }
    86  
    87  // EncodeItem ...
    88  func (d DoubleFlower) EncodeItem() (name string, meta int16) {
    89  	return "minecraft:double_plant", int16(d.Type.Uint8())
    90  }
    91  
    92  // EncodeBlock ...
    93  func (d DoubleFlower) EncodeBlock() (string, map[string]any) {
    94  	return "minecraft:double_plant", map[string]any{"double_plant_type": d.Type.String(), "upper_block_bit": d.UpperPart}
    95  }
    96  
    97  // allDoubleFlowers ...
    98  func allDoubleFlowers() (b []world.Block) {
    99  	for _, d := range DoubleFlowerTypes() {
   100  		b = append(b, DoubleFlower{Type: d, UpperPart: true})
   101  		b = append(b, DoubleFlower{Type: d, UpperPart: false})
   102  	}
   103  	return
   104  }