2022-01-20 21:58:50 +08:00
|
|
|
package entity
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"edgaru089.ml/go/gl01/internal/util/itype"
|
|
|
|
"edgaru089.ml/go/gl01/internal/world"
|
|
|
|
)
|
|
|
|
|
|
|
|
// EntityBehaviour describes the behaviour of a type of entity with the same Name.
|
2022-02-01 23:48:39 +08:00
|
|
|
// It should hold no data of its own.
|
2022-01-20 21:58:50 +08:00
|
|
|
type EntityBehaviour interface {
|
|
|
|
// Name returns the type Name of the behaviour.
|
|
|
|
Name() string
|
|
|
|
|
2022-02-01 23:48:39 +08:00
|
|
|
// Hitbox gets the hitbox(s) of the entity.
|
2022-01-20 21:58:50 +08:00
|
|
|
//
|
2022-02-01 23:48:39 +08:00
|
|
|
// The hitbox is in entity-local coordinates, originating from the position.
|
|
|
|
Hitbox(pos itype.Vec3d, dataset itype.Dataset) []itype.Boxd
|
2022-01-20 21:58:50 +08:00
|
|
|
|
|
|
|
// EyeHeight gets the height of the eye of the entity.
|
|
|
|
EyeHeight(pos itype.Vec3d, dataset itype.Dataset) float64
|
|
|
|
|
|
|
|
// Update is called on every frame.
|
2022-02-01 23:48:39 +08:00
|
|
|
// It should be used to update the behaviour of the entity.
|
2022-01-20 21:58:50 +08:00
|
|
|
Update(pos itype.Vec3d, dataset itype.Dataset, world *world.World, deltaTime time.Duration)
|
|
|
|
}
|
|
|
|
|
|
|
|
var behaviour = make(map[string]EntityBehaviour)
|
|
|
|
|
|
|
|
// RegisterEntityBehaviour registers behaviour with the name of b.Name().
|
|
|
|
//
|
|
|
|
// If the name is already taken, false is returned and nothing is done.
|
|
|
|
// Otherwise, true is returned and the entity is registered.
|
|
|
|
func RegisterEntityBehaviour(b EntityBehaviour) bool {
|
|
|
|
if _, ok := behaviour[b.Name()]; ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
behaviour[b.Name()] = b
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Entity is a struct holding a Behaviour, a Position and a Speed.
|
|
|
|
type Entity struct {
|
|
|
|
b EntityBehaviour
|
2022-02-01 23:48:39 +08:00
|
|
|
pos, speed itype.Vec3d // pos should have a origin of the **center of the bottom** of the hitbox
|
2022-01-20 21:58:50 +08:00
|
|
|
ds itype.Dataset
|
|
|
|
|
|
|
|
name string // a shortcut to b.Name(), the typename
|
|
|
|
|
2022-02-01 23:48:39 +08:00
|
|
|
// physics stuff
|
2022-01-20 21:58:50 +08:00
|
|
|
onGround bool
|
|
|
|
worldbox []itype.Boxd
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewEntity(typename string, pos itype.Vec3d) *Entity {
|
|
|
|
var b EntityBehaviour
|
|
|
|
var ok bool
|
|
|
|
if b, ok = behaviour[typename]; !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &Entity{
|
|
|
|
b: b,
|
|
|
|
pos: pos,
|
|
|
|
name: typename,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) Position() itype.Vec3d {
|
|
|
|
return e.pos
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) SetPosition(pos itype.Vec3d) {
|
|
|
|
e.pos = pos
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) Speed() itype.Vec3d {
|
|
|
|
return e.speed
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) SetSpeed(speed itype.Vec3d) {
|
|
|
|
e.speed = speed
|
|
|
|
}
|
|
|
|
|
2022-02-01 23:48:39 +08:00
|
|
|
func (e *Entity) Hitbox() []itype.Boxd {
|
2022-01-20 21:58:50 +08:00
|
|
|
return e.b.Hitbox(e.pos, e.ds)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) Accelerate(x, y, z float64) {
|
2022-02-01 23:48:39 +08:00
|
|
|
e.speed[0] += x
|
2022-01-20 21:58:50 +08:00
|
|
|
e.speed[1] += y
|
2022-02-01 23:48:39 +08:00
|
|
|
e.speed[2] += z
|
|
|
|
/*vec := itype.Vec3d{x, y, z}
|
|
|
|
e.speed = util.BunnyhopAccelerate(vec, e.speed, vec.Length(), 8)*/
|
2022-01-20 21:58:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) OnGround() bool {
|
|
|
|
return e.onGround
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) EyeHeight() float64 {
|
|
|
|
return e.b.EyeHeight(e.pos, e.ds)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Entity) EyePosition() itype.Vec3d {
|
|
|
|
return e.pos.Addv(0, e.EyeHeight(), 0)
|
|
|
|
}
|