package entity import ( "time" "edgaru089.ink/go/gl01/internal/util/itype" "edgaru089.ink/go/gl01/internal/world" ) // EntityBehaviour describes the behaviour of a type of entity with the same Name. // It should hold no data of its own. type EntityBehaviour interface { // Name returns the type Name of the behaviour. Name() string // Hitbox gets the hitbox(s) of the entity. // // The hitbox is in entity-local coordinates, originating from the position. Hitbox(pos itype.Vec3d, dataset itype.Dataset) []itype.Boxd // EyeHeight gets the height of the eye of the entity. EyeHeight(pos itype.Vec3d, dataset itype.Dataset) float64 // Update is called on every frame. // It should be used to update the behaviour of the entity. 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 pos, speed itype.Vec3d // pos should have a origin of the **center of the bottom** of the hitbox ds itype.Dataset name string // a shortcut to b.Name(), the typename // physics stuff 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, ds: make(itype.Dataset), } } 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 } func (e *Entity) Hitbox() []itype.Boxd { return e.b.Hitbox(e.pos, e.ds) } func (e *Entity) Accelerate(x, y, z float64) { e.speed[0] += x e.speed[1] += y e.speed[2] += z /*vec := itype.Vec3d{x, y, z} e.speed = util.BunnyhopAccelerate(vec, e.speed, vec.Length(), 8)*/ } 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) } 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 }