github.com/df-mc/dragonfly@v0.9.13/server/entity/item.go (about)

     1  package entity
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/block/cube"
     5  	"github.com/df-mc/dragonfly/server/internal/nbtconv"
     6  	"github.com/df-mc/dragonfly/server/item"
     7  	"github.com/df-mc/dragonfly/server/world"
     8  	"github.com/go-gl/mathgl/mgl64"
     9  	"time"
    10  )
    11  
    12  // NewItem creates a new item entity using the item stack passed. The item
    13  // entity will be positioned at the position passed. If the stack's count
    14  // exceeds its max count, the count of the stack will be changed to the
    15  // maximum.
    16  func NewItem(i item.Stack, pos mgl64.Vec3) *Ent {
    17  	return Config{Behaviour: itemConf.New(i)}.New(ItemType{}, pos)
    18  }
    19  
    20  // NewItemPickupDelay creates a new item entity containing item stack i. A
    21  // delay may be specified which defines for how long the item stack cannot be
    22  // picked up from the ground.
    23  func NewItemPickupDelay(i item.Stack, pos mgl64.Vec3, delay time.Duration) *Ent {
    24  	config := itemConf
    25  	config.PickupDelay = delay
    26  	return Config{Behaviour: config.New(i)}.New(ItemType{}, pos)
    27  }
    28  
    29  var itemConf = ItemBehaviourConfig{
    30  	Gravity: 0.04,
    31  	Drag:    0.02,
    32  }
    33  
    34  // ItemType is a world.EntityType implementation for Item.
    35  type ItemType struct{}
    36  
    37  func (ItemType) EncodeEntity() string   { return "minecraft:item" }
    38  func (ItemType) NetworkOffset() float64 { return 0.125 }
    39  func (ItemType) BBox(world.Entity) cube.BBox {
    40  	return cube.Box(-0.125, 0, -0.125, 0.125, 0.25, 0.125)
    41  }
    42  
    43  func (ItemType) DecodeNBT(m map[string]any) world.Entity {
    44  	i := nbtconv.MapItem(m, "Item")
    45  	if i.Empty() {
    46  		return nil
    47  	}
    48  	n := NewItem(i, nbtconv.Vec3(m, "Pos"))
    49  	n.SetVelocity(nbtconv.Vec3(m, "Motion"))
    50  	n.age = time.Duration(nbtconv.Int16(m, "Age")) * (time.Second / 20)
    51  	n.Behaviour().(*ItemBehaviour).pickupDelay = time.Duration(nbtconv.Int64(m, "PickupDelay")) * (time.Second / 20)
    52  	return n
    53  }
    54  
    55  func (ItemType) EncodeNBT(e world.Entity) map[string]any {
    56  	it := e.(*Ent)
    57  	b := it.Behaviour().(*ItemBehaviour)
    58  	return map[string]any{
    59  		"Health":      int16(5),
    60  		"Age":         int16(it.Age() / (time.Second * 20)),
    61  		"PickupDelay": int64(b.pickupDelay / (time.Second * 20)),
    62  		"Pos":         nbtconv.Vec3ToFloat32Slice(it.Position()),
    63  		"Motion":      nbtconv.Vec3ToFloat32Slice(it.Velocity()),
    64  		"Item":        nbtconv.WriteItem(b.Item(), true),
    65  	}
    66  }