func RoomAreEqualFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "RoomsAreEqual", game.LuaRoom, game.LuaRoom) { return 0 } r1 := game.LuaToRoom(L, a.ent.Game(), -2) r2 := game.LuaToRoom(L, a.ent.Game(), -1) L.PushBoolean(r1 == r2) return 1 } }
// Returns a list of rooms representing a path from src to dst. The path will // not include src, but will include dst. This function will return nil if // the path requires going through more than a single unexplored room, this // means that you can use this to path to an unexplored room, but you cannot // use it to path to a room further in the house than that. // rooms. // Format // path = roomPath(src, dst) // // Input: // src - Room to start the path from. // dst - Room to end the path at. // // Output: // path - array - A list of rooms that connect src to dst, excluding src // but including dst. func RoomPathFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "roomPath", game.LuaRoom, game.LuaRoom) { return 0 } me := a.ent g := me.Game() graph := g.RoomGraph() r1 := game.LuaToRoom(L, g, -2) r2 := game.LuaToRoom(L, g, -1) if r1 == nil || r2 == nil { game.LuaDoError(L, fmt.Sprintf("Referenced one or more invalid rooms.")) return 0 } L.PushString("room") L.GetTable(-3) r1_index := L.ToInteger(-1) L.Pop(1) L.PushString("room") L.GetTable(-2) r2_index := L.ToInteger(-1) L.Pop(1) cost, path := algorithm.Dijkstra(graph, []int{r1_index}, []int{r2_index}) if cost == -1 { L.PushNil() return 1 } num_unexplored := 0 for _, v := range path { if !me.Info.RoomsExplored[v] { num_unexplored++ } } if num_unexplored > 1 { L.PushNil() return 1 } L.NewTable() for i, v := range path { if i == 0 { continue } // Skip this one because we're in it already L.PushInteger(i) game.LuaPushRoom(L, g, g.House.Floors[0].Rooms[v]) L.SetTable(-3) } return 1 } }
// Returns a list of all doors between two rooms. // Format // doors = allDoorsBetween(r1, r2) // // Input: // r1 - room - A room. // r2 - room - Another room. // // Output: // doors - array[door] - List of all doors connecting r1 and r2. func AllDoorsBetween(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "allDoorsBetween", game.LuaRoom, game.LuaRoom) { return 0 } room1 := game.LuaToRoom(L, a.ent.Game(), -2) room2 := game.LuaToRoom(L, a.ent.Game(), -1) if room1 == nil || room2 == nil { game.LuaDoError(L, "AllDoorsBetween: Specified an invalid door.") return 0 } // TODO: Check for floors! // if f1 != f2 { // // Rooms on different floors can theoretically be connected in the // // future by a stairway, but right now that doesn't happen. // L.NewTable() // return 1 // } L.NewTable() count := 1 for _, door1 := range room1.Doors { for _, door2 := range room2.Doors { _, d := a.ent.Game().House.Floors[0].FindMatchingDoor(room1, door1) if d == door2 { L.PushInteger(count) count++ game.LuaPushDoor(L, a.ent.Game(), door1) L.SetTable(-3) } } } return 1 } }
// Returns a list of all positions that the specified door can be opened and // closed from. // Format // ps = doorPositions(d) // // Input: // d - door - A door. // // Output: // ps - array[table[x,y]] - List of all position this door can be opened // and closed from. func DoorPositionsFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "DoorPositions", game.LuaDoor) { return 0 } room := game.LuaToRoom(L, a.ent.Game(), -1) door := game.LuaToDoor(L, a.ent.Game(), -1) if door == nil || room == nil { game.LuaDoError(L, "DoorPositions: Specified an invalid door.") return 0 } var x, y, dx, dy int switch door.Facing { case house.FarLeft: x = door.Pos y = room.Size.Dy - 1 dx = 1 case house.FarRight: x = room.Size.Dx - 1 y = door.Pos dy = 1 case house.NearLeft: x = -1 y = door.Pos dy = 1 case house.NearRight: x = door.Pos y = -1 dx = 1 default: game.LuaDoError(L, fmt.Sprintf("Found a door with a bad facing.")) } L.NewTable() count := 1 for i := 0; i < door.Width; i++ { L.PushInteger(count*2 - 1) game.LuaPushPoint(L, room.X+x+dx*i, room.Y+y+dy*i) L.SetTable(-3) L.PushInteger(count * 2) game.LuaPushPoint(L, room.X+x+dx*i+dy, room.Y+y+dy*i+dx) L.SetTable(-3) count++ } return 1 } }
// Returns a list of all doors attached to the specified room. // Format // room = allDoorsOn(r) // // Input: // r - room - A room. // // Output: // doors - array[door] - List of all doors attached to the specified room. func AllDoorsOn(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "allDoorsOn", game.LuaRoom) { return 0 } room := game.LuaToRoom(L, a.ent.Game(), -1) if room == nil { game.LuaDoError(L, "Specified an invalid room.") return 0 } L.NewTable() for i := range room.Doors { L.PushInteger(i + 1) game.LuaPushDoor(L, a.ent.Game(), room.Doors[i]) L.SetTable(-3) } return 1 } }
// Returns a list of all positions inside the specified room. // Format // ps = roomPositions(r) // // Input: // r - room - A room. // // Output: // ps - array[table[x,y]] - List of all position inside the specified room. func RoomPositionsFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "roomPositions", game.LuaRoom) { return 0 } room := game.LuaToRoom(L, a.ent.Game(), -1) if room == nil { game.LuaDoError(L, "RoomPositions: Specified an invalid room.") return 0 } L.NewTable() count := 1 for x := room.X; x < room.X+room.Size.Dx; x++ { for y := room.Y; y < room.Y+room.Size.Dy; y++ { L.PushInteger(count) count++ game.LuaPushPoint(L, x, y) L.SetTable(-3) } } return 1 } }