/** * Get the value of all cell flags at a position. * @param L Lua context. * @return Number of results of the call. */ static int l_map_getcellflags(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); if(lua_type(L, 4) != LUA_TTABLE) { lua_settop(L, 3); lua_createtable(L, 0, 1); } else { lua_settop(L, 4); } // Fill Lua table with the flags and numbers of the node. for (auto val : lua_node_flag_map) { add_cellflag(L, pNode, val.second, val.first); } add_cellint(L, pNode->iRoomId, "roomId"); add_cellint(L, pNode->iParcelId, "parcelId"); add_cellint(L, pNode->iFlags >> 24, "thob"); return 1; }
static int l_anim_set_tile(lua_State *L) { T* pAnimation = luaT_testuserdata<T>(L); if(lua_isnoneornil(L, 2)) { pAnimation->removeFromTile(); lua_pushnil(L); luaT_setenvfield(L, 1, "map"); lua_settop(L, 1); } else { THMap* pMap = luaT_testuserdata<THMap>(L, 2); THMapNode* pNode = pMap->getNode(luaL_checkint(L, 3) - 1, luaL_checkint(L, 4) - 1); if(pNode) pAnimation->attachToTile(pNode, lastLayer); else { luaL_argerror(L, 3, lua_pushfstring(L, "Map index out of bounds (" LUA_NUMBER_FMT "," LUA_NUMBER_FMT ")", lua_tonumber(L, 3), lua_tonumber(L, 4))); } lua_settop(L, 2); luaT_setenvfield(L, 1, "map"); } return 1; }
static int l_map_getcell(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) { return luaL_argerror(L, 2, lua_pushfstring(L, "Map co-ordinates out " "of bounds (%d, %d)", iX + 1, iY + 1)); } if(lua_isnoneornil(L, 4)) { lua_pushinteger(L, pNode->iBlock[0]); lua_pushinteger(L, pNode->iBlock[1]); lua_pushinteger(L, pNode->iBlock[2]); lua_pushinteger(L, pNode->iBlock[3]); return 4; } else { lua_Integer iLayer = luaL_checkinteger(L, 4) - 1; if(iLayer < 0 || iLayer >= 4) return luaL_argerror(L, 4, "Layer index is out of bounds (1-4)"); lua_pushinteger(L, pNode->iBlock[iLayer]); return 1; } }
static int l_map_setcell(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); if(lua_gettop(L) >= 7) { pNode->iBlock[0] = (uint16_t)luaL_checkinteger(L, 4); pNode->iBlock[1] = (uint16_t)luaL_checkinteger(L, 5); pNode->iBlock[2] = (uint16_t)luaL_checkinteger(L, 6); pNode->iBlock[3] = (uint16_t)luaL_checkinteger(L, 7); } else { lua_Integer iLayer = luaL_checkinteger(L, 4) - 1; if(iLayer < 0 || iLayer >= 4) return luaL_argerror(L, 4, "Layer index is out of bounds (1-4)"); uint16_t iBlock = static_cast<uint16_t>(luaL_checkinteger(L, 5)); pNode->iBlock[iLayer] = iBlock; } lua_settop(L, 1); return 1; }
static int l_map_gettemperature(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2)) - 1; int iY = static_cast<int>(luaL_checkinteger(L, 3)) - 1; const THMapNode* pNode = pMap->getNode(iX, iY); uint16_t iTemp = pMap->getNodeTemperature(pNode); lua_pushnumber(L, static_cast<lua_Number>(iTemp) / static_cast<lua_Number>(65535)); return 1; }
/* because all the thobs are not retrieved when the map is loaded in c lua objects use the afterLoad function to be registered after a load, if the object list would not be cleared it would result in duplication of thobs in the object list. */ static int l_map_erase_thobs(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); pNode->objects.clear(); return 1; }
static int l_map_setcellflags(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); luaL_checktype(L, 4, LUA_TTABLE); lua_settop(L, 4); lua_pushnil(L); while(lua_next(L, 4)) { if(lua_type(L, 5) == LUA_TSTRING) { const char *field = lua_tostring(L, 5); auto iter = lua_node_flag_map.find(field); if(iter != lua_node_flag_map.end()) { if (lua_toboolean(L, 6) == 0) pNode->flags[(*iter).second] = false; else pNode->flags[(*iter).second] = true; } else if (std::strcmp(field, "thob") == 0) { auto thob = static_cast<THObjectType>(lua_tointeger(L, 6)); pNode->objects.push_back(thob); } else if(std::strcmp(field, "parcelId") == 0) { pNode->iParcelId = static_cast<uint16_t>(lua_tointeger(L, 6)); } else if(std::strcmp(field, "roomId") == 0) { pNode->iRoomId = static_cast<uint16_t>(lua_tointeger(L,6)); } else { luaL_error(L, "Invalid flag \'%s\'", field); } } lua_settop(L, 5); } return 0; }
static int l_map_remove_cell_thob(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); int thob = static_cast<int>(luaL_checkinteger(L, 4)); if(pNode->pExtendedObjectList == nullptr) { if(static_cast<int>((pNode->iFlags & 0xFF000000) >> 24) == thob) { pNode->iFlags &= 0x00FFFFFF; } } else {
static int l_map_remove_cell_thob(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); auto thob = static_cast<THObjectType>(luaL_checkinteger(L, 4)); for(auto iter = pNode->objects.begin(); iter != pNode->objects.end(); iter++) { if(*iter == thob) { pNode->objects.erase(iter); break; } } return 1; }
/* because all the thobs are not retrieved when the map is loaded in c lua objects use the afterLoad function to be registered after a load, if the object list would not be cleared it would result in duplication of thobs in the object list. */ static int l_map_erase_thobs(lua_State *L) { THMap* pMap = luaT_testuserdata<THMap>(L); int iX = static_cast<int>(luaL_checkinteger(L, 2) - 1); // Lua arrays start at 1 - pretend int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too. THMapNode* pNode = pMap->getNode(iX, iY); if(pNode == nullptr) return luaL_argerror(L, 2, "Map co-ordinates out of bounds"); if(pNode->iFlags & THMN_ObjectsAlreadyErased) { // after the last load the map node already has had its object type list erased // so the call must be ignored return 2; } if(pNode->pExtendedObjectList) delete pNode->pExtendedObjectList; pNode->pExtendedObjectList = nullptr; pNode->iFlags &= 0x00FFFFFF; //erase thob pNode->iFlags |= THMN_ObjectsAlreadyErased; return 1; }