int KHero::LuaAISay(Lua_State* L)
{
	BOOL bResult 	    = false;
	BOOL bRetCode	    = false;
	int	 nTopIndex	    = 0;
    int  nTalkChannel   = 0;
    int  nMsgType       = trRoom;
    const char* szMessage = NULL;
    DWORD dwTalkID      = ERROR_ID;
    char* szTalkerName  = m_szName;
	
	nTopIndex = Lua_GetTopIndex(L);
	KGLOG_PROCESS_ERROR(nTopIndex == 2);

    nTalkChannel = (int)Lua_ValueToNumber(L, 1);
    KGLOG_PROCESS_ERROR(nTalkChannel == KAI_TALK_CHANNEL_MAP || nTalkChannel == KAI_TALK_CHANNEL_TEAM);

    szMessage = Lua_ValueToString(L, 2);
    KGLOG_PROCESS_ERROR(szMessage);

    if (nTalkChannel == KAI_TALK_CHANNEL_TEAM)
        nMsgType = trTeam;

    if (m_pOwner)
    {
        dwTalkID = m_pOwner->m_dwID;
        szTalkerName = m_pOwner->m_szName;
    }

    for (KObjEnumerator it = m_pScene->GetObjEnumerator(); it.HasElement(); it.MoveToNext())
    {
        KSceneObject* pObj = it.GetValue();
        if (!pObj->Is(sotHero))
            continue;

        KHero* pHero = (KHero*)pObj;
        KPlayer* pOwner = pHero->GetOwner();
        if (!pOwner)
            continue;
        if (pOwner->m_pFightingHero != pHero)
            continue;

        if (nTalkChannel == KAI_TALK_CHANNEL_TEAM && pHero->m_nSide != m_nSide)
            continue;

        g_PlayerServer.DoTalkMessage(nMsgType, dwTalkID, szTalkerName, m_dwID,  ERROR_ID, pOwner->m_dwID, pOwner->m_szName, strlen(szMessage), szMessage);
    }

	bResult = true;
Exit0:
	Lua_PushBoolean(L, bResult);
	return 1;
}
int KScene::LuaAddCandyBagOnBasket(Lua_State* L)
{
    BOOL                    bResult             = false;
    BOOL                    bRetCode            = false;
    int                     nTopIndex           = 0;
    DWORD                   dwCandyTemplateID   = ERROR_ID;
    int                     nSide               = 0;
    int                     nBasketFloor        = 0;
    KSceneObjectTemplate*   pTemplate           = NULL;
    KSceneObject*           pObj                = NULL;
    KCandyBag*              pCandyBag           = NULL;
    KBasket*                pBasket             = NULL;

    nTopIndex = Lua_GetTopIndex(L);
    KGLOG_PROCESS_ERROR(nTopIndex == 3);

    dwCandyTemplateID   = (DWORD)Lua_ValueToNumber(L, 1);
    nSide               = (int)Lua_ValueToNumber(L, 2);
    nBasketFloor        = (int)Lua_ValueToNumber(L, 3);
    
    pTemplate = g_pSO3World->m_Settings.m_ObjTemplate.GetTemplate(dwCandyTemplateID);
    KGLOG_PROCESS_ERROR(pTemplate);
    KGLOG_PROCESS_ERROR(pTemplate->m_nType == sotCandyBag);

    KGLOG_PROCESS_ERROR(nSide == sidLeft || nSide == sidRight);
    KGLOG_PROCESS_ERROR(nBasketFloor >= bfFirst && nBasketFloor <= bfSixth);

    pBasket = GetBasket(nSide, nBasketFloor);
    KGLOG_PROCESS_ERROR(pBasket);

    pObj = m_pSceneObjMgr->AddByTemplate(dwCandyTemplateID);
    KGLOG_PROCESS_ERROR(pObj);
    KGLOG_PROCESS_ERROR(pObj->Is(sotCandyBag));

    pCandyBag = (KCandyBag*)pObj;
    pCandyBag->FixTo(pBasket->GetPosition());

    g_PlayerServer.DoSyncSceneObject(pCandyBag, -1);

    bResult = true;
Exit0:
    if (!bResult)
    {
        if (pCandyBag)
        {
            pCandyBag->SetDeleteFlag();
            pCandyBag = NULL;
        }
    }

    Lua_PushBoolean(L, bResult);
    return 1;
}
int KScene::LuaShowAllHeroAI(Lua_State* L)
{
    int nAILevel = 0;

    KGLogPrintf(KGLOG_INFO, "Begin ShowAllHeroAI ...");
    
    for (KObjEnumerator it = GetObjEnumerator(); it.HasElement(); it.GetValue())
    {
        KSceneObject* pObj = it.GetValue();
        if (!pObj->Is(sotHero))
            continue;

        KHero* pHero = (KHero*)pObj;

        g_pSO3World->m_AIManager.GetAILevel(pHero->m_AIData.nAIType, nAILevel);

        KGLogPrintf(KGLOG_INFO, "Hero ID:%u, Sid:%d, SeatPos:%d, IsAIMode:%d, AILevel:%d, AIType:%d", 
            pHero->m_dwID, pHero->m_nSide, pHero->m_nPos, pHero->m_bAiMode, pHero->m_AIData.nAIType, nAILevel);
    }

    KGLogPrintf(KGLOG_INFO, "End ShowAllHeroAI ...");

    return 0;
}