doodle/pkg/uix/scripting.go
Noah Petherbridge 9201475060 Update Doodad JS API + Hostile mobs
New functions are available on the JavaScript API for doodads:

* Actors.At(Point) []*Actor: returns actors intersecting a point
* Actors.FindPlayer() *Actor: returns the nearest player character
* Actors.New(filename string): create a new actor (NOT TESTED YET!)
* Self.Grounded() bool: query the grounded status of current actor

With this the game's built-in doodads have been revised:

* Bird: will now scan 240 pixels diagonally searching for the player
  character and will dive if seen. The Bird is dangerous while
  diving. It will return to its original altitude once it touches
  the ground.
* Azulians: the Azulians are now dangerous to player characters but
  not to the Thief. Azulians will begin to follow the player when
  they are within the aggro range and will hop if the player is
  above them to try and overcome obstacles.
  * Blue Azulian: aggro is (250, 100) jump speed 12 movement 2
  * Red Azulian: aggro is (250, 200) jump speed 14 movement 4
2022-01-17 21:28:05 -08:00

112 lines
3.1 KiB
Go

package uix
import (
"git.kirsle.net/apps/doodle/pkg/doodads"
"git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/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.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
},
})
}
// 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,
// functions
"ID": actor.ID,
"Size": func() render.Rect {
var size = actor.Doodad().ChunkSize()
return render.NewRect(size, size)
},
"GetTag": actor.Doodad().Tag,
"Position": actor.Position,
"MoveTo": func(p render.Point) {
actor.MoveTo(p)
actor.SetGrounded(false)
},
"Grounded": actor.Grounded,
"SetHitbox": actor.SetHitbox,
"Hitbox": actor.Hitbox,
"SetVelocity": actor.SetVelocity,
"GetVelocity": actor.Velocity,
"SetMobile": actor.SetMobile,
"SetInventory": actor.SetInventory,
"HasInventory": actor.HasInventory,
"SetGravity": actor.SetGravity,
"AddAnimation": actor.AddAnimation,
"IsAnimating": actor.IsAnimating,
"IsPlayer": actor.IsPlayer,
"PlayAnimation": actor.PlayAnimation,
"StopAnimation": actor.StopAnimation,
"ShowLayer": actor.ShowLayer,
"ShowLayerNamed": actor.ShowLayerNamed,
"Inventory": actor.Inventory,
"AddItem": actor.AddItem,
"RemoveItem": actor.RemoveItem,
"HasItem": actor.HasItem,
"ClearInventory": actor.ClearInventory,
"Destroy": actor.Destroy,
"Hide": actor.Hide,
"Show": actor.Show,
"GetLinks": func() []map[string]interface{} {
var result = []map[string]interface{}{}
for _, linked := range w.GetLinkedActors(actor) {
result = append(result, w.MakeSelfAPI(linked))
}
return result
},
}
}