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

     1  package entity
     2  
     3  import (
     4  	"github.com/df-mc/dragonfly/server/block/cube"
     5  	"github.com/df-mc/dragonfly/server/block/cube/trace"
     6  	"github.com/df-mc/dragonfly/server/internal/nbtconv"
     7  	"github.com/df-mc/dragonfly/server/world"
     8  	"github.com/df-mc/dragonfly/server/world/particle"
     9  	"github.com/df-mc/dragonfly/server/world/sound"
    10  	"github.com/go-gl/mathgl/mgl64"
    11  )
    12  
    13  // NewEnderPearl creates an EnderPearl entity. EnderPearl is a smooth, greenish-
    14  // blue item used to teleport.
    15  func NewEnderPearl(pos mgl64.Vec3, owner world.Entity) *Ent {
    16  	return Config{Behaviour: enderPearlConf.New(owner)}.New(EnderPearlType{}, pos)
    17  }
    18  
    19  var enderPearlConf = ProjectileBehaviourConfig{
    20  	Gravity:  0.03,
    21  	Drag:     0.01,
    22  	Particle: particle.EndermanTeleport{},
    23  	Sound:    sound.Teleport{},
    24  	Hit:      teleport,
    25  }
    26  
    27  // teleporter represents a living entity that can teleport.
    28  type teleporter interface {
    29  	// Teleport teleports the entity to the position given.
    30  	Teleport(pos mgl64.Vec3)
    31  	Living
    32  }
    33  
    34  // teleport teleports the owner of an Ent to a trace.Result's position.
    35  func teleport(e *Ent, target trace.Result) {
    36  	if user, ok := e.Behaviour().(*ProjectileBehaviour).Owner().(teleporter); ok {
    37  		e.World().PlaySound(user.Position(), sound.Teleport{})
    38  		user.Teleport(target.Position())
    39  		user.Hurt(5, FallDamageSource{})
    40  	}
    41  }
    42  
    43  // EnderPearlType is a world.EntityType implementation for EnderPearl.
    44  type EnderPearlType struct{}
    45  
    46  func (EnderPearlType) EncodeEntity() string { return "minecraft:ender_pearl" }
    47  func (EnderPearlType) BBox(world.Entity) cube.BBox {
    48  	return cube.Box(-0.125, 0, -0.125, 0.125, 0.25, 0.125)
    49  }
    50  
    51  func (EnderPearlType) DecodeNBT(m map[string]any) world.Entity {
    52  	ep := NewEnderPearl(nbtconv.Vec3(m, "Pos"), nil)
    53  	ep.vel = nbtconv.Vec3(m, "Motion")
    54  	return ep
    55  }
    56  
    57  func (EnderPearlType) EncodeNBT(e world.Entity) map[string]any {
    58  	ep := e.(*Ent)
    59  	return map[string]any{
    60  		"Pos":    nbtconv.Vec3ToFloat32Slice(ep.Position()),
    61  		"Motion": nbtconv.Vec3ToFloat32Slice(ep.Velocity()),
    62  	}
    63  }