Noah Petherbridge
c4456ac51b
Updates the Self API to expose more uix.Actor fields: * Doodad() * GetBoundingRect() * HasGravity() * IsFrozen() * IsMobile() * LayerCount() * ListItems() * SetGrounded() * SetWet() * Velocity() - note: it was Self.GetVelocity() before. Self.GetVelocity is deprecated and made an alias to Velocity.
190 lines
5.2 KiB
Go
190 lines
5.2 KiB
Go
package uix
|
|
|
|
import (
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/doodads"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/level"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/log"
|
|
"git.kirsle.net/SketchyMaze/doodle/pkg/scripting"
|
|
"git.kirsle.net/go/render"
|
|
)
|
|
|
|
// Functions relating to the Doodad JavaScript API for Canvas Actors.
|
|
|
|
// MakeScriptAPI makes several useful globals available to doodad
|
|
// scripts such as Actors.At()
|
|
func (w *Canvas) MakeScriptAPI(vm *scripting.VM) {
|
|
vm.Set("Actors", map[string]interface{}{
|
|
// Actors.At(Point)
|
|
"At": func(p render.Point) []*Actor {
|
|
var result = []*Actor{}
|
|
|
|
for _, actor := range w.actors {
|
|
var box = actor.Hitbox().AddPoint(actor.Position())
|
|
if actor != nil && p.Inside(box) {
|
|
result = append(result, actor)
|
|
}
|
|
}
|
|
|
|
return result
|
|
},
|
|
|
|
// Actors.FindPlayer: returns the nearest player character.
|
|
"FindPlayer": func() *Actor {
|
|
for _, actor := range w.actors {
|
|
if actor.IsPlayer() {
|
|
return actor
|
|
}
|
|
}
|
|
return nil
|
|
},
|
|
|
|
// Actors.CameraFollowPlayer tells the camera to follow the player character.
|
|
"CameraFollowPlayer": func() {
|
|
for _, actor := range w.actors {
|
|
if actor.IsPlayer() {
|
|
w.FollowActor = actor.ID()
|
|
}
|
|
}
|
|
},
|
|
|
|
// Actors.New: create a new actor.
|
|
"New": func(filename string) *Actor {
|
|
doodad, err := doodads.LoadFile(filename)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
actor := NewActor("_new", &level.Actor{}, doodad)
|
|
w.AddActor(actor)
|
|
|
|
// Set up the player character's script in the VM.
|
|
if err := w.scripting.AddLevelScript(actor.ID(), filename); err != nil {
|
|
log.Error("Actors.New(%s): scripting.InstallActor(player) failed: %s", filename, err)
|
|
}
|
|
|
|
return actor
|
|
},
|
|
|
|
// Actors.SetPlayerCharacter: remake the player character.
|
|
"SetPlayerCharacter": func(filename string) {
|
|
if w.OnSetPlayerCharacter != nil {
|
|
w.OnSetPlayerCharacter(filename)
|
|
} else {
|
|
log.Error("Actors.SetPlayerCharacter: caller was not ready")
|
|
}
|
|
},
|
|
})
|
|
|
|
vm.Set("Level", map[string]interface{}{
|
|
"Difficulty": w.level.GameRule.Difficulty,
|
|
"ResetTimer": func() {
|
|
if w.OnResetTimer != nil {
|
|
w.OnResetTimer()
|
|
} else {
|
|
log.Error("Level.ResetTimer: caller was not ready")
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
// MakeSelfAPI generates the `Self` object for the scripting API in
|
|
// reference to a live Canvas actor in the level.
|
|
func (w *Canvas) MakeSelfAPI(actor *Actor) map[string]interface{} {
|
|
return map[string]interface{}{
|
|
"Filename": actor.Doodad().Filename,
|
|
"Title": actor.Doodad().Title,
|
|
|
|
/*
|
|
Unique options to the Self API over regular Actors.
|
|
*/
|
|
|
|
"GetLinks": func() []map[string]interface{} {
|
|
var result = []map[string]interface{}{}
|
|
for _, linked := range w.GetLinkedActors(actor) {
|
|
result = append(result, w.MakeSelfAPI(linked))
|
|
}
|
|
return result
|
|
},
|
|
|
|
// Attract the camera's attention.
|
|
"CameraFollowMe": func() {
|
|
// Update the doodad that the camera should focus on.
|
|
w.FollowActor = actor.ID()
|
|
},
|
|
|
|
// functions
|
|
|
|
"GetTag": actor.Doodad().Tag,
|
|
|
|
/*
|
|
Expose the uix.Actor API surface area, in the same order
|
|
that these functions are defined in their respective files
|
|
to keep it easy to maintain.
|
|
*/
|
|
|
|
// actor.go
|
|
"ID": actor.ID,
|
|
"Doodad": actor.Doodad,
|
|
"SetGravity": actor.SetGravity,
|
|
"SetMobile": actor.SetMobile,
|
|
"SetInventory": actor.SetInventory,
|
|
"IsMobile": actor.IsMobile,
|
|
"IsPlayer": actor.IsPlayer,
|
|
"HasInventory": actor.HasInventory,
|
|
"HasGravity": actor.HasGravity,
|
|
"Invulnerable": actor.Invulnerable,
|
|
"SetInvulnerable": actor.SetInvulnerable,
|
|
"IsWet": actor.IsWet,
|
|
"IsOnScreen": actor.IsOnScreen,
|
|
"SetWet": actor.SetWet,
|
|
"Size": actor.Size,
|
|
"Velocity": actor.Velocity,
|
|
"GetVelocity": actor.Velocity, // TODO: deprecated, old Self.GetVelocity inconsistency
|
|
"SetVelocity": actor.SetVelocity,
|
|
"Position": actor.Position,
|
|
"MoveTo": func(p render.Point) {
|
|
actor.MoveTo(p)
|
|
actor.SetGrounded(false)
|
|
},
|
|
"MoveBy": func(p render.Point) {
|
|
actor.MoveBy(p)
|
|
actor.SetGrounded(false)
|
|
},
|
|
"Grounded": actor.Grounded,
|
|
"SetGrounded": actor.SetGrounded,
|
|
"IsCoyoteTime": actor.IsCoyoteTime,
|
|
"Hide": actor.Hide,
|
|
"Show": actor.Show,
|
|
"Freeze": actor.Freeze,
|
|
"Unfreeze": actor.Unfreeze,
|
|
"IsFrozen": actor.IsFrozen,
|
|
// Not: SetUsing, SetNoclip
|
|
"AddItem": actor.AddItem,
|
|
"RemoveItem": actor.RemoveItem,
|
|
"ClearInventory": actor.ClearInventory,
|
|
"HasItem": actor.HasItem,
|
|
"ListItems": actor.ListItems,
|
|
"Inventory": actor.Inventory,
|
|
"GetBoundingRect": actor.GetBoundingRect,
|
|
"SetHitbox": actor.SetHitbox,
|
|
"Hitbox": actor.Hitbox,
|
|
"Options": actor.Options,
|
|
"GetOption": func(name string) interface{} {
|
|
opt := actor.GetOption(name)
|
|
if opt == nil {
|
|
return nil
|
|
}
|
|
return opt.Value
|
|
},
|
|
"LayerCount": actor.LayerCount,
|
|
"ShowLayer": actor.ShowLayer,
|
|
"ShowLayerNamed": actor.ShowLayerNamed,
|
|
"Destroy": actor.Destroy,
|
|
|
|
// actor_animation.go
|
|
"AddAnimation": actor.AddAnimation,
|
|
"PlayAnimation": actor.PlayAnimation,
|
|
"IsAnimating": actor.IsAnimating,
|
|
"StopAnimation": actor.StopAnimation,
|
|
}
|
|
}
|