// Gets the id out of the table at the specified index and returns the // associated Entity, or nil if there is none. func LuaToEntity(L *lua.State, game *Game, index int) *Entity { L.PushString("id") L.GetTable(index - 1) id := EntityId(L.ToInteger(-1)) L.Pop(1) return game.EntityById(id) }
func UpdatePlayer(p *Player, L *lua.State) { buffer := bytes.NewBuffer(nil) L.GetGlobal("store") err := LuaEncodeTable(buffer, L, -1) if err != nil { base.Warn().Printf("Error encoding lua state: %v", err) } L.Pop(1) p.Lua_store = buffer.Bytes() }
func LuaToSpawnPoint(L *lua.State, game *Game, pos int) *house.SpawnPoint { L.PushString("id") L.GetTable(pos - 1) index := L.ToInteger(-1) L.Pop(1) if index < 0 || index >= len(game.House.Floors[0].Spawns) { return nil } return game.House.Floors[0].Spawns[index] }
func LuaToPoint(L *lua.State, pos int) (x, y int) { L.PushString("X") L.GetTable(pos - 1) x = L.ToInteger(-1) L.Pop(1) L.PushString("Y") L.GetTable(pos - 1) y = L.ToInteger(-1) L.Pop(1) return }
func LuaEncodeTable(w io.Writer, L *lua.State, index int) error { L.PushNil() for L.Next(index-1) != 0 { binary.Write(w, binary.LittleEndian, byte(1)) err := LuaEncodeValue(w, L, -2) if err != nil { return err } err = LuaEncodeValue(w, L, -1) if err != nil { return err } L.Pop(1) } return binary.Write(w, binary.LittleEndian, byte(0)) }
func LuaToRoom(L *lua.State, game *Game, index int) *house.Room { L.PushString("floor") L.GetTable(index - 1) floor := L.ToInteger(-1) L.Pop(1) L.PushString("room") L.GetTable(index - 1) room := L.ToInteger(-1) L.Pop(1) if floor < 0 || floor >= len(game.House.Floors) { return nil } if room < 0 || room >= len(game.House.Floors[floor].Rooms) { return nil } return game.House.Floors[floor].Rooms[room] }
// Encodes a lua value, only bool, number, nil, table, and string can be // encoded. If an unencodable value is encountered an error will be // returned. func LuaEncodeValue(w io.Writer, L *lua.State, index int) error { var err1, err2, err3 error switch { case L.IsBoolean(index): err1 = binary.Write(w, binary.LittleEndian, luaEncBool) var v byte = 0 if L.ToBoolean(index) { v = 1 } err2 = binary.Write(w, binary.LittleEndian, v) case L.IsNumber(index): err1 = binary.Write(w, binary.LittleEndian, luaEncNumber) err2 = binary.Write(w, binary.LittleEndian, L.ToNumber(index)) case L.IsNil(index): err1 = binary.Write(w, binary.LittleEndian, luaEncNil) case LuaIsEntity(L, index): err1 = binary.Write(w, binary.LittleEndian, luaEncEntity) L.PushString("id") L.GetTable(index - 1) err2 = binary.Write(w, binary.LittleEndian, uint64(L.ToInteger(-1))) L.Pop(1) case L.IsTable(index): err1 = binary.Write(w, binary.LittleEndian, luaEncTable) err2 = LuaEncodeTable(w, L, index) case L.IsString(index): err1 = binary.Write(w, binary.LittleEndian, luaEncString) str := L.ToString(index) err2 = binary.Write(w, binary.LittleEndian, uint32(len(str))) err3 = binary.Write(w, binary.LittleEndian, []byte(str)) default: return errors.New(fmt.Sprintf("Cannot encode lua type id == %d.", L.Type(index))) } switch { case err1 != nil: return err1 case err2 != nil: return err2 case err3 != nil: return err3 } return nil }
func LuaStringifyParam(L *lua.State, index int) string { if L.IsTable(index) { str := "table <not implemented> {" return str first := true L.PushNil() for L.Next(index-1) != 0 { if !first { str += ", " } first = false str += fmt.Sprintf("(%s) -> (%s)", LuaStringifyParam(L, -2), LuaStringifyParam(L, -1)) L.Pop(1) } return str + "}" } if L.IsBoolean(index) { if L.ToBoolean(index) { return "true" } return "false" } return L.ToString(index) }
func LuaIsEntity(L *lua.State, index int) bool { L.PushString("type") L.GetTable(index - 1) if L.IsNil(-1) { L.Pop(1) return false } if L.ToString(-1) == "Entity" { L.Pop(1) return true } L.Pop(1) return false }
func LuaCheckParamsOk(L *lua.State, name string, params ...LuaType) bool { fmt.Sprintf("%s(") n := L.GetTop() if n != len(params) { LuaDoError(L, fmt.Sprintf("Got %d parameters to %s.", n, luaMakeSigniature(name, params))) return false } for i := -n; i < 0; i++ { ok := false switch params[i+n] { case LuaInteger: ok = L.IsNumber(i) case LuaFloat: ok = L.IsNumber(i) case LuaBoolean: ok = L.IsBoolean(i) case LuaString: ok = L.IsString(i) case LuaEntity: if L.IsTable(i) { L.PushNil() for L.Next(i-1) != 0 { if L.ToString(-2) == "type" && L.ToString(-1) == "Entity" { ok = true } L.Pop(1) } } case LuaPoint: if L.IsTable(i) { var x, y bool L.PushNil() for L.Next(i-1) != 0 { if L.ToString(-2) == "X" { x = true } if L.ToString(-2) == "Y" { y = true } L.Pop(1) } ok = x && y } case LuaRoom: if L.IsTable(i) { var floor, room, door bool L.PushNil() for L.Next(i-1) != 0 { switch L.ToString(-2) { case "floor": floor = true case "room": room = true case "door": door = true } L.Pop(1) } ok = floor && room && !door } case LuaDoor: if L.IsTable(i) { var floor, room, door bool L.PushNil() for L.Next(i-1) != 0 { switch L.ToString(-2) { case "floor": floor = true case "room": room = true case "door": door = true } L.Pop(1) } ok = floor && room && door } case LuaSpawnPoint: if L.IsTable(i) { L.PushNil() for L.Next(i-1) != 0 { if L.ToString(-2) == "type" && L.ToString(-1) == "SpawnPoint" { ok = true } L.Pop(1) } } case LuaArray: // Make sure that all of the indices 1..length are there, and no others. check := make(map[int]int) if L.IsTable(i) { L.PushNil() for L.Next(i-1) != 0 { if L.IsNumber(-2) { check[L.ToInteger(-2)]++ } else { break } L.Pop(1) } } count := 0 for i := 1; i <= len(check); i++ { if _, ok := check[i]; ok { count++ } } ok = (count == len(check)) case LuaTable: ok = L.IsTable(i) case LuaAnything: ok = true } if !ok { LuaDoError(L, fmt.Sprintf("Unexpected parameters to %s.", luaMakeSigniature(name, params))) return false } } return true }