gl01/internal/entity/entity.go

136 lines
3.1 KiB
Go
Raw Normal View History

2022-01-20 21:58:50 +08:00
package entity
import (
"time"
"edgaru089.ink/go/gl01/internal/util/itype"
"edgaru089.ink/go/gl01/internal/world"
2022-01-20 21:58:50 +08:00
)
// 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,
2022-02-24 20:20:33 +08:00
ds: make(itype.Dataset),
2022-01-20 21:58:50 +08:00
}
}
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)
}
2022-02-24 20:20:33 +08:00
func (e *Entity) DatasetI(name string) int64 {
return e.ds[name].(int64)
}
func (e *Entity) DatasetF(name string) float64 {
return e.ds[name].(float64)
}
func (e *Entity) DatasetS(name string) string {
return e.ds[name].(string)
}
func (e *Entity) DatasetB(name string) bool {
return e.ds[name].(bool)
}
func (e *Entity) SetDatasetI(name string, val int64) {
e.ds[name] = val
}
func (e *Entity) SetDatasetF(name string, val float64) {
e.ds[name] = val
}
func (e *Entity) SetDatasetS(name string, val string) {
e.ds[name] = val
}
func (e *Entity) SetDatasetB(name string, val bool) {
e.ds[name] = val
}