static int l_anim_get_tile(lua_State *L) { THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L); lua_settop(L, 1); lua_getfenv(L, 1); lua_getfield(L, 2, "map"); lua_replace(L, 2); if(lua_isnil(L, 2)) { return 0; } THMap* pMap = (THMap*)lua_touserdata(L, 2); const THLinkList* pListNode = pAnimation->getPrevious(); while(pListNode->m_pPrev) { pListNode = pListNode->m_pPrev; } // Casting pListNode to a THMapNode* is slightly dubious, but it should // work. If on the normal list, then pListNode will be a THMapNode*, and // all is fine. However, if on the early list, pListNode will be pointing // to a member of a THMapNode, so we're relying on pointer arithmetic // being a subtract and integer divide by sizeof(THMapNode) to yield the // correct map node. const THMapNode *pRootNode = pMap->getNodeUnchecked(0, 0); uintptr_t iDiff = reinterpret_cast<const char*>(pListNode) - reinterpret_cast<const char*>(pRootNode); int iIndex = (int)(iDiff / sizeof(THMapNode)); int iY = iIndex / pMap->getWidth(); int iX = iIndex - (iY * pMap->getWidth()); lua_pushinteger(L, iX + 1); lua_pushinteger(L, iY + 1); return 3; // map, x, y }