示例#1
0
static int l_anim_get_anim(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    lua_pushinteger(L, pAnimation->getAnimation());

    return 1;
}
示例#2
0
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
}
示例#3
0
static int l_anim_set_crop(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    pAnimation->setCropColumn(luaL_checkint(L, 2));
    lua_settop(L, 1);
    return 1;
}
示例#4
0
static int l_anim_set_frame(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    pAnimation->setFrame(luaL_checkinteger(L, 2));
    lua_settop(L, 1);
    return 1;
}
示例#5
0
static int l_anim_set_parent(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    THAnimation* pParent = luaT_testuserdata<THAnimation>(L, 2, luaT_environindex, false);
    pAnimation->setParent(pParent);
    lua_settop(L, 1);
    return 1;
}
示例#6
0
static int l_anim_get_position(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);

    lua_pushinteger(L, pAnimation->getX());
    lua_pushinteger(L, pAnimation->getY());

    return 2;
}
示例#7
0
static int l_anim_get_secondary_marker(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    int iX = 0;
    int iY = 0;
    pAnimation->getSecondaryMarker(&iX, &iY);
    lua_pushinteger(L, iX);
    lua_pushinteger(L, iY);
    return 2;
}
示例#8
0
static int l_anim_set_layers_from(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    const THAnimation* pAnimationSrc = luaT_testuserdata<THAnimation>(L, 2, luaT_environindex);

    pAnimation->setLayersFrom(pAnimationSrc);

    lua_settop(L, 1);
    return 1;
}
示例#9
0
static bool THAnimation_isMultipleFrameAnimation(THDrawable* pSelf)
{
    THAnimation *pAnimation = reinterpret_cast<THAnimation *>(pSelf);
    if(pAnimation)
    {
        int firstFrame = pAnimation->getAnimationManager()->getFirstFrame(pAnimation->getAnimation());
        int nextFrame = pAnimation->getAnimationManager()->getNextFrame(firstFrame);
        return nextFrame != firstFrame;
    }
    else
        return false;
   
}
示例#10
0
static int l_anim_set_morph(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    THAnimation* pMorphTarget = luaT_testuserdata<THAnimation>(L, 2, luaT_environindex);

    unsigned int iDurationFactor = 1;
    if(!lua_isnoneornil(L, 3) && luaL_checkint(L, 3) > 0)
        iDurationFactor = luaL_checkint(L, 3);

    pAnimation->setMorphTarget(pMorphTarget, iDurationFactor);
    lua_settop(L, 2);
    luaT_setenvfield(L, 1, "morph_target");

    return 1;
}
示例#11
0
static int l_anim_set_anim(lua_State *L)
{
    THAnimation* pAnimation = luaT_testuserdata<THAnimation>(L);
    THAnimationManager* pManager = luaT_testuserdata<THAnimationManager>(L, 2);
    int iAnim = luaL_checkint(L, 3);
    if(iAnim < 0 || (unsigned int)iAnim >= pManager->getAnimationCount())
        luaL_argerror(L, 3, "Animation index out of bounds");

    if(lua_isnoneornil(L, 4))
        pAnimation->setFlags(0);
    else
        pAnimation->setFlags(luaL_checkint(L, 4));

    pAnimation->setAnimation(pManager, iAnim);
    lua_settop(L, 2);
    luaT_setenvfield(L, 1, "animator");
    lua_pushnil(L);
    luaT_setenvfield(L, 1, "morph_target");

    return 1;
}
示例#12
0
static int l_map_updateblueprint(lua_State *L)
{
    // NB: This function can be implemented in Lua, but is implemented in C for
    // efficiency.
    const unsigned short iFloorTileGood = 24 + (THDF_Alpha50 << 8);
    const unsigned short iFloorTileGoodCenter = 37 + (THDF_Alpha50 << 8);
    const unsigned short iFloorTileBad  = 67 + (THDF_Alpha50 << 8);
    const unsigned int iWallAnimTopCorner = 124;
    const unsigned int iWallAnim = 120;

    THMap* pMap = luaT_testuserdata<THMap>(L);
    int iOldX = static_cast<int>(luaL_checkinteger(L, 2)) - 1;
    int iOldY = static_cast<int>(luaL_checkinteger(L, 3)) - 1;
    int iOldW = static_cast<int>(luaL_checkinteger(L, 4));
    int iOldH = static_cast<int>(luaL_checkinteger(L, 5));
    int iNewX = static_cast<int>(luaL_checkinteger(L, 6)) - 1;
    int iNewY = static_cast<int>(luaL_checkinteger(L, 7)) - 1;
    int iNewW = static_cast<int>(luaL_checkinteger(L, 8));
    int iNewH = static_cast<int>(luaL_checkinteger(L, 9));
    luaL_checktype(L, 10, LUA_TTABLE); // Animation list
    THAnimationManager* pAnims = luaT_testuserdata<THAnimationManager>(L, 11, luaT_upvalueindex(1));
    bool entire_invalid = lua_toboolean(L, 12) != 0;
    bool valid = !entire_invalid;

    if(iOldX < 0 || iOldY < 0 || (iOldX + iOldW) > pMap->getWidth() || (iOldY + iOldH) > pMap->getHeight())
        luaL_argerror(L, 2, "Old rectangle is out of bounds");
    if(iNewX < 0 || iNewY < 0 || (iNewX + iNewW) >= pMap->getWidth() || (iNewY + iNewH) >= pMap->getHeight())
        luaL_argerror(L, 6, "New rectangle is out of bounds");

    // Clear blueprint flag from previous selected floor tiles (copying it to the passable flag).
    for(int iY = iOldY; iY < iOldY + iOldH; ++iY)
    {
        for(int iX = iOldX; iX < iOldX + iOldW; ++iX)
        {
            THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
            pNode->iBlock[3] = 0;
            uint32_t iFlags = pNode->iFlags;
            iFlags |= ((iFlags & THMN_PassableIfNotForBlueprint) != 0) ? THMN_Passable : 0;
            iFlags &= ~THMN_PassableIfNotForBlueprint;
            pNode->iFlags = iFlags;
        }
    }

    // Add blueprint flag to new floor tiles.
    for(int iY = iNewY; iY < iNewY + iNewH; ++iY)
    {
        for(int iX = iNewX; iX < iNewX + iNewW; ++iX)
        {
            THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
            if(is_valid(entire_invalid, pNode))
                pNode->iBlock[3] = iFloorTileGood;
            else
            {
                pNode->iBlock[3] = iFloorTileBad;
                valid = false;
            }
            pNode->iFlags |= ((pNode->iFlags & THMN_Passable) != 0) ? THMN_PassableIfNotForBlueprint : 0;
        }
    }

    // Set center floor tiles
    if(iNewW >= 2 && iNewH >= 2)
    {
        int iCenterX = iNewX + (iNewW - 2) / 2;
        int iCenterY = iNewY + (iNewH - 2) / 2;

        THMapNode *pNode = pMap->getNodeUnchecked(iCenterX, iCenterY);
        if(pNode->iBlock[3] == iFloorTileGood)
            pNode->iBlock[3] = iFloorTileGoodCenter + 2;

        pNode = pMap->getNodeUnchecked(iCenterX + 1, iCenterY);
        if(pNode->iBlock[3] == iFloorTileGood)
            pNode->iBlock[3] = iFloorTileGoodCenter + 1;

        pNode = pMap->getNodeUnchecked(iCenterX, iCenterY + 1);
        if(pNode->iBlock[3] == iFloorTileGood)
            pNode->iBlock[3] = iFloorTileGoodCenter + 0;

        pNode = pMap->getNodeUnchecked(iCenterX + 1, iCenterY + 1);
        if(pNode->iBlock[3] == iFloorTileGood)
            pNode->iBlock[3] = iFloorTileGoodCenter + 3;
    }

    // Set wall animations
    int iNextAnim = 1;
    THAnimation *pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
    THMapNode *pNode = pMap->getNodeUnchecked(iNewX, iNewY);
    pAnim->setAnimation(pAnims, iWallAnimTopCorner);
    pAnim->setFlags(THDF_ListBottom | (is_valid(entire_invalid, pNode) ? 0 : THDF_AltPalette));
    pAnim->attachToTile(pNode, 0);

    for(int iX = iNewX; iX < iNewX + iNewW; ++iX)
    {
        if(iX != iNewX)
        {
            pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
            pNode = pMap->getNodeUnchecked(iX, iNewY);
            pAnim->setAnimation(pAnims, iWallAnim);
            pAnim->setFlags(THDF_ListBottom | (is_valid(entire_invalid, pNode) ? 0 : THDF_AltPalette));
            pAnim->attachToTile(pNode, 0);
            pAnim->setPosition(0, 0);
        }
        pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
        pNode = pMap->getNodeUnchecked(iX, iNewY + iNewH - 1);
        pAnim->setAnimation(pAnims, iWallAnim);
        pAnim->setFlags(THDF_ListBottom | (is_valid(entire_invalid, pNode) ? 0 : THDF_AltPalette));
        pNode = pMap->getNodeUnchecked(iX, iNewY + iNewH);
        pAnim->attachToTile(pNode, 0);
        pAnim->setPosition(0, -1);
    }
    for(int iY = iNewY; iY < iNewY + iNewH; ++iY)
    {
        if(iY != iNewY)
        {
            pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
            pNode = pMap->getNodeUnchecked(iNewX, iY);
            pAnim->setAnimation(pAnims, iWallAnim);
            pAnim->setFlags(THDF_ListBottom | THDF_FlipHorizontal | (is_valid(entire_invalid, pNode) ? 0 : THDF_AltPalette));
            pAnim->attachToTile(pNode, 0);
            pAnim->setPosition(2, 0);
        }
        pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
        pNode = pMap->getNodeUnchecked(iNewX + iNewW - 1, iY);
        pAnim->setAnimation(pAnims, iWallAnim);
        pAnim->setFlags(THDF_ListBottom | THDF_FlipHorizontal | (is_valid(entire_invalid, pNode) ? 0 : THDF_AltPalette));
        pNode = pMap->getNodeUnchecked(iNewX + iNewW, iY);
        pAnim->attachToTile(pNode, 0);
        pAnim->setPosition(2, -1);
    }

    // Clear away extra animations
    int iAnimCount = (int)lua_objlen(L, 10);
    if(iAnimCount >= iNextAnim)
    {
        for(int i = iNextAnim; i <= iAnimCount; ++i)
        {
            pAnim = l_map_updateblueprint_getnextanim(L, iNextAnim);
            pAnim->removeFromTile();
            lua_pushnil(L);
            lua_rawseti(L, 10, i);
        }
    }

    lua_pushboolean(L, valid ? 1 : 0);
    return 1;
}