up3
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/df-mc/dragonfly/server/block"
|
||||
"github.com/df-mc/dragonfly/server/world"
|
||||
"github.com/go-gl/mathgl/mgl64"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PassiveBehaviourConfig holds optional parameters for a PassiveBehaviour.
|
||||
type PassiveBehaviourConfig struct {
|
||||
// Gravity is the amount of Y velocity subtracted every tick.
|
||||
Gravity float64
|
||||
// Drag is used to reduce all axes of the velocity every tick. Velocity is
|
||||
// multiplied with (1-Drag) every tick.
|
||||
Drag float64
|
||||
// ExistenceDuration is the duration that an entity with this behaviour
|
||||
// should last. Once this time expires, the entity is closed. If
|
||||
// ExistenceDuration is 0, the entity will never expire automatically.
|
||||
ExistenceDuration time.Duration
|
||||
// Expire is called when the entity expires due to its age reaching the
|
||||
// ExistenceDuration.
|
||||
Expire func(e *Ent, tx *world.Tx)
|
||||
// Tick is called for every tick that the entity is alive. Tick is called
|
||||
// after the entity moves on a tick.
|
||||
Tick func(e *Ent, tx *world.Tx)
|
||||
}
|
||||
|
||||
func (conf PassiveBehaviourConfig) Apply(data *world.EntityData) {
|
||||
data.Data = conf.New()
|
||||
}
|
||||
|
||||
// New creates a PassiveBehaviour using the parameters in conf.
|
||||
func (conf PassiveBehaviourConfig) New() *PassiveBehaviour {
|
||||
if conf.ExistenceDuration == 0 {
|
||||
conf.ExistenceDuration = math.MaxInt64
|
||||
}
|
||||
return &PassiveBehaviour{conf: conf, fuse: conf.ExistenceDuration, mc: &MovementComputer{
|
||||
Gravity: conf.Gravity,
|
||||
Drag: conf.Drag,
|
||||
DragBeforeGravity: true,
|
||||
}}
|
||||
}
|
||||
|
||||
// PassiveBehaviour implements Behaviour for entities that act passively. This
|
||||
// means that they can move, but only under influence of the environment, which
|
||||
// includes, for example, falling, and flowing water.
|
||||
type PassiveBehaviour struct {
|
||||
conf PassiveBehaviourConfig
|
||||
mc *MovementComputer
|
||||
|
||||
close bool
|
||||
fallDistance float64
|
||||
fuse time.Duration
|
||||
}
|
||||
|
||||
// Explode adds velocity to a passive entity to blast it away from the
|
||||
// explosion's source.
|
||||
func (p *PassiveBehaviour) Explode(e *Ent, src mgl64.Vec3, impact float64, _ block.ExplosionConfig) {
|
||||
e.data.Vel = e.data.Vel.Add(e.data.Pos.Sub(src).Normalize().Mul(impact))
|
||||
}
|
||||
|
||||
// Fuse returns the leftover time until PassiveBehaviourConfig.Expire is called,
|
||||
// or -1 if this function is not set.
|
||||
func (p *PassiveBehaviour) Fuse() time.Duration {
|
||||
if p.conf.Expire != nil {
|
||||
return p.fuse
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// Tick implements the behaviour for a passive entity. It performs movement and
|
||||
// updates its state.
|
||||
func (p *PassiveBehaviour) Tick(e *Ent, tx *world.Tx) *Movement {
|
||||
if p.close {
|
||||
_ = e.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
m := p.mc.TickMovement(e, e.data.Pos, e.data.Vel, e.data.Rot, tx)
|
||||
e.data.Pos, e.data.Vel = m.pos, m.vel
|
||||
p.fallDistance = math.Max(p.fallDistance-m.dvel[1], 0)
|
||||
|
||||
p.fuse = p.conf.ExistenceDuration - e.Age()
|
||||
|
||||
if p.conf.Tick != nil {
|
||||
p.conf.Tick(e, tx)
|
||||
}
|
||||
|
||||
if p.Fuse()%(time.Second/4) == 0 {
|
||||
for _, v := range tx.Viewers(m.pos) {
|
||||
v.ViewEntityState(e)
|
||||
}
|
||||
}
|
||||
|
||||
if e.Age() > p.conf.ExistenceDuration {
|
||||
p.close = true
|
||||
if p.conf.Expire != nil {
|
||||
p.conf.Expire(e, tx)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
Reference in New Issue
Block a user