github.com/df-mc/dragonfly@v0.9.13/server/entity/experience_orb.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/world"
     7  	"github.com/go-gl/mathgl/mgl64"
     8  	"slices"
     9  	"time"
    10  )
    11  
    12  // orbSplitSizes contains split sizes used for dropping experience orbs.
    13  var orbSplitSizes = []int{2477, 1237, 617, 307, 149, 73, 37, 17, 7, 3, 1}
    14  
    15  // NewExperienceOrbs takes in a position and an amount and automatically splits the amount into multiple orbs, returning
    16  // a slice of the created orbs.
    17  func NewExperienceOrbs(pos mgl64.Vec3, amount int) (orbs []*Ent) {
    18  	for amount > 0 {
    19  		size := orbSplitSizes[slices.IndexFunc(orbSplitSizes, func(value int) bool {
    20  			return amount >= value
    21  		})]
    22  
    23  		orbs = append(orbs, NewExperienceOrb(pos, size))
    24  		amount -= size
    25  	}
    26  	return
    27  }
    28  
    29  // NewExperienceOrb creates a new experience orb and returns it.
    30  func NewExperienceOrb(pos mgl64.Vec3, xp int) *Ent {
    31  	conf := experienceOrbConf
    32  	conf.Experience = xp
    33  	return Config{Behaviour: conf.New()}.New(ExperienceOrbType{}, pos)
    34  }
    35  
    36  var experienceOrbConf = ExperienceOrbBehaviourConfig{
    37  	Gravity: 0.04,
    38  	Drag:    0.02,
    39  }
    40  
    41  // ExperienceOrbType is a world.EntityType implementation for ExperienceOrb.
    42  type ExperienceOrbType struct{}
    43  
    44  func (ExperienceOrbType) EncodeEntity() string { return "minecraft:xp_orb" }
    45  func (ExperienceOrbType) BBox(world.Entity) cube.BBox {
    46  	return cube.Box(-0.125, 0, -0.125, 0.125, 0.25, 0.125)
    47  }
    48  
    49  func (ExperienceOrbType) DecodeNBT(m map[string]any) world.Entity {
    50  	o := NewExperienceOrb(nbtconv.Vec3(m, "Pos"), int(nbtconv.Int32(m, "Value")))
    51  	o.vel = nbtconv.Vec3(m, "Motion")
    52  	o.age = time.Duration(nbtconv.Int16(m, "Age")) * (time.Second / 20)
    53  	return o
    54  }
    55  
    56  func (ExperienceOrbType) EncodeNBT(e world.Entity) map[string]any {
    57  	orb := e.(*Ent)
    58  	return map[string]any{
    59  		"Age":    int16(orb.Age() / (time.Second * 20)),
    60  		"Value":  int32(orb.Behaviour().(*ExperienceOrbBehaviour).Experience()),
    61  		"Pos":    nbtconv.Vec3ToFloat32Slice(orb.Position()),
    62  		"Motion": nbtconv.Vec3ToFloat32Slice(orb.Velocity()),
    63  	}
    64  }