func LuaPushRoom(L *lua.State, game *Game, room *house.Room) { for fi, f := range game.House.Floors { for ri, r := range f.Rooms { if r == room { L.NewTable() L.PushString("type") L.PushString("room") L.SetTable(-3) L.PushString("floor") L.PushInteger(fi) L.SetTable(-3) L.PushString("room") L.PushInteger(ri) L.SetTable(-3) L.PushString("Pos") LuaPushPoint(L, room.X, room.Y) L.SetTable(-3) L.PushString("Dims") LuaPushDims(L, room.Size.Dx, room.Size.Dy) L.SetTable(-3) return } } } L.PushNil() }
func LuaPushSmartFunctionTable(L *lua.State, ft FunctionTable) { // Copy it just in case - I can't imagine someone changing it after passing // it to this function, but I don't want to take any chances. myft := make(FunctionTable) for n, f := range ft { myft[n] = f } names := make([]string, len(myft))[0:0] for name := range myft { names = append(names, name) } sort.Strings(names) valid_selectors := "[" for i, name := range names { if i > 0 { valid_selectors += ", " } valid_selectors += fmt.Sprintf("'%s'", name) } valid_selectors += "]." L.NewTable() L.PushString("__index") L.PushGoFunction(func(L *lua.State) int { name := L.ToString(-1) if f, ok := myft[name]; ok { f() } else { base.Error().Printf("'%s' is not a valid selector, valid seletors are %s", name, valid_selectors) L.PushNil() } return 1 }) L.SetTable(-3) }
func LuaPushPoint(L *lua.State, x, y int) { L.NewTable() L.PushString("X") L.PushInteger(x) L.SetTable(-3) L.PushString("Y") L.PushInteger(y) L.SetTable(-3) }
func (exec aoeExec) Push(L *lua.State, g *game.Game) { exec.BasicActionExec.Push(L, g) if L.IsNil(-1) { return } L.PushString("Pos") game.LuaPushPoint(L, exec.X, exec.Y) L.SetTable(-3) }
func LuaPushDims(L *lua.State, dx, dy int) { L.NewTable() L.PushString("Dx") L.PushInteger(dx) L.SetTable(-3) L.PushString("Dy") L.PushInteger(dy) L.SetTable(-3) }
func (exec basicAttackExec) Push(L *lua.State, g *game.Game) { exec.BasicActionExec.Push(L, g) if L.IsNil(-1) { return } target := g.EntityById(exec.Target) L.PushString("Target") game.LuaPushEntity(L, target) L.SetTable(-3) }
func (exec summonExec) Push(L *lua.State, g *game.Game) { exec.BasicActionExec.Push(L, g) if L.IsNil(-1) { return } _, x, y := g.FromVertex(exec.Pos) L.PushString("Pos") game.LuaPushPoint(L, x, y) L.SetTable(-3) }
func LuaPushDoor(L *lua.State, game *Game, door *house.Door) { for fi, f := range game.House.Floors { for ri, r := range f.Rooms { for di, d := range r.Doors { if d == door { L.NewTable() L.PushString("type") L.PushString("door") L.SetTable(-3) L.PushString("floor") L.PushInteger(fi) L.SetTable(-3) L.PushString("room") L.PushInteger(ri) L.SetTable(-3) L.PushString("door") L.PushInteger(di) L.SetTable(-3) return } } } } L.PushNil() }
func (bae BasicActionExec) Push(L *lua.State, g *Game) { ent := g.EntityById(bae.Ent) if bae.Index < 0 || bae.Index >= len(ent.Actions) { base.Error().Printf("Tried to push an exec for an invalid action index: '%s' %d.", ent.Name) L.PushNil() return } L.NewTable() L.PushString("Action") ent.Actions[bae.Index].Push(L) L.SetTable(-3) L.PushString("Ent") LuaPushEntity(L, ent) L.SetTable(-3) }
func (exec *moveExec) Push(L *lua.State, g *game.Game) { exec.BasicActionExec.Push(L, g) if L.IsNil(-1) { return } L.PushString("Path") L.NewTable() for i := range exec.Path { L.PushInteger(i + 1) _, x, y := g.FromVertex(exec.Path[i]) game.LuaPushPoint(L, x, y) L.SetTable(-3) } L.SetTable(-3) }
func (exec interactExec) Push(L *lua.State, g *game.Game) { exec.BasicActionExec.Push(L, g) if L.IsNil(-1) { return } L.PushString("Toggle Door") L.PushBoolean(exec.Toggle_door) L.SetTable(-3) if exec.Toggle_door { L.PushString("Door") game.LuaPushDoor(L, g, exec.getDoor(g)) } else { L.PushString("Target") game.LuaPushEntity(L, g.EntityById(exec.Target)) } L.SetTable(-3) }
// decodes a lua table and pushes it onto the stack func LuaDecodeTable(r io.Reader, L *lua.State, g *Game) error { L.NewTable() var cont byte err := binary.Read(r, binary.LittleEndian, &cont) for cont != 0 && err == nil { for i := 0; i < 2 && err == nil; i++ { err = LuaDecodeValue(r, L, g) } if err == nil { err = binary.Read(r, binary.LittleEndian, &cont) } L.SetTable(-3) } if err != nil { return err } return nil }
func (a *Interact) Push(L *lua.State) { L.NewTable() L.PushString("Type") L.PushString("Interact") L.SetTable(-3) L.PushString("Ap") L.PushInteger(a.Ap) L.SetTable(-3) L.PushString("Range") L.PushInteger(a.Range) L.SetTable(-3) }
func (a *AoeAttack) Push(L *lua.State) { L.NewTable() L.PushString("Type") L.PushString("Aoe Attack") L.SetTable(-3) L.PushString("Name") L.PushString(a.Name) L.SetTable(-3) L.PushString("Ap") L.PushInteger(a.Ap) L.SetTable(-3) L.PushString("Damage") L.PushInteger(a.Damage) L.SetTable(-3) L.PushString("Strength") L.PushInteger(a.Strength) L.SetTable(-3) L.PushString("Range") L.PushInteger(a.Range) L.SetTable(-3) L.PushString("Diameter") L.PushInteger(a.Diameter) L.SetTable(-3) L.PushString("Ammo") if a.Current_ammo == -1 { L.PushInteger(1000) } else { L.PushInteger(a.Current_ammo) } L.SetTable(-3) }
func (a *SummonAction) Push(L *lua.State) { L.NewTable() L.PushString("Type") L.PushString("Summon") L.SetTable(-3) L.PushString("Name") L.PushString(a.Name) L.SetTable(-3) L.PushString("Ap") L.PushInteger(a.Ap) L.SetTable(-3) L.PushString("Entity") L.PushString(a.Ent_name) L.SetTable(-3) L.PushString("Los") L.PushBoolean(a.Personal_los) L.SetTable(-3) L.PushString("Range") L.PushInteger(a.Range) L.SetTable(-3) L.PushString("Ammo") if a.Current_ammo == -1 { L.PushInteger(1000) } else { L.PushInteger(a.Current_ammo) } L.SetTable(-3) }
func LuaPushSpawnPoint(L *lua.State, game *Game, sp *house.SpawnPoint) { index := -1 for i, spawn := range game.House.Floors[0].Spawns { if spawn == sp { index = i } } if index == -1 { LuaDoError(L, "Unable to push SpawnPoint, not found in the house.") L.NewTable() L.PushString("id") L.PushInteger(-1) L.SetTable(-3) L.PushString("type") L.PushString("SpawnPoint") L.SetTable(-3) return } L.NewTable() x, y := sp.Pos() dx, dy := sp.Dims() L.PushString("id") L.PushInteger(index) L.SetTable(-3) L.PushString("type") L.PushString("SpawnPoint") L.SetTable(-3) L.PushString("Name") L.PushString(sp.Name) L.SetTable(-3) L.PushString("Pos") LuaPushPoint(L, x, y) L.SetTable(-3) L.PushString("Dims") LuaPushDims(L, dx, dy) L.SetTable(-3) }
func (a *Move) Push(L *lua.State) { L.NewTable() L.PushString("Type") L.PushString("Move") L.SetTable(-3) }
// Pushes an entity onto the stack, it is a table containing the following: // e.id -> EntityId of this entity // e.name -> Name as displayed to the user // e.gear_options -> Table mapping gear to icon for all available gear // e.gear -> Name of the selected gear, nil if none is selected // e.actions -> Array of actions this entity has available func LuaPushEntity(L *lua.State, _ent *Entity) { if _ent == nil { L.PushNil() return } // id and Name can be added to the ent table as static data since they // never change. L.NewTable() L.PushString("Name") L.PushString(_ent.Name) L.SetTable(-3) L.PushString("id") L.PushInteger(int(_ent.Id)) L.SetTable(-3) L.PushString("type") L.PushString("Entity") L.SetTable(-3) id := _ent.Id // Meta table for the Entity so that any dynamic data is generated // on-the-fly LuaPushSmartFunctionTable(L, FunctionTable{ "Conditions": func() { ent := _ent.Game().EntityById(id) L.NewTable() for _, condition := range ent.Stats.ConditionNames() { L.PushString(condition) L.PushBoolean(true) L.SetTable(-3) } }, "Side": func() { ent := _ent.Game().EntityById(id) L.NewTable() sides := map[string]Side{ "Denizen": SideHaunt, "Intruder": SideExplorers, "Npc": SideNpc, "Object": SideObject, } for str, side := range sides { L.PushString(str) L.PushBoolean(ent.Side() == side) L.SetTable(-3) } }, "State": func() { ent := _ent.Game().EntityById(id) L.PushString(ent.Sprite().State()) }, "Master": func() { ent := _ent.Game().EntityById(id) L.NewTable() for key, val := range ent.Ai_data { L.PushString(key) L.PushString(val) L.SetTable(-3) } }, "GearOptions": func() { ent := _ent.Game().EntityById(id) L.NewTable() if ent.ExplorerEnt != nil { for _, gear_name := range ent.ExplorerEnt.Gear_names { var g Gear g.Defname = gear_name base.GetObject("gear", &g) L.PushString(gear_name) L.PushString(g.Large_icon.Path.String()) L.SetTable(-3) } } }, "Gear": func() { ent := _ent.Game().EntityById(id) if ent.ExplorerEnt != nil && ent.ExplorerEnt.Gear != nil { L.PushString(ent.ExplorerEnt.Gear.Name) } else { L.PushNil() } }, "Actions": func() { ent := _ent.Game().EntityById(id) L.NewTable() for _, action := range ent.Actions { L.PushString(action.String()) action.Push(L) L.SetTable(-3) } }, "Pos": func() { ent := _ent.Game().EntityById(id) x, y := ent.Pos() LuaPushPoint(L, x, y) }, "Corpus": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.Corpus()) }, "Ego": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.Ego()) }, "HpCur": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.HpCur()) }, "HpMax": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.HpMax()) }, "ApCur": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.ApCur()) }, "ApMax": func() { ent := _ent.Game().EntityById(id) L.PushInteger(ent.Stats.ApMax()) }, "Info": func() { ent := _ent.Game().EntityById(id) L.NewTable() L.PushString("LastEntityThatIAttacked") LuaPushEntity(L, ent.Game().EntityById(ent.Info.LastEntThatIAttacked)) L.SetTable(-3) L.PushString("LastEntThatAttackedMe") LuaPushEntity(L, ent.Game().EntityById(ent.Info.LastEntThatAttackedMe)) L.SetTable(-3) }, }) L.SetMetaTable(-2) }