C++ Game NPC任务基本信息查询

// 接口声明

DECLARE_ENTITY("", QuestQuery, IEntity);
DECLARE_METHOD_T(QuestQuery, GetTrackList);
DECLARE_METHOD_T(QuestQuery, GetBranchAreaList);
DECLARE_METHOD_1(int, QuestQuery, GetQuestID, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetQuestTitle, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetQuestObj, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetQuestDetails, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestAwardID, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestState, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestType, int);
DECLARE_METHOD_1(int, QuestQuery, GetAcceptType, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestTimeType, int);
DECLARE_METHOD_1(bool, QuestQuery, GetQuestCanShare, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestLevel, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestMinLevel, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestTrackIndex, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestTrackState, int);
DECLARE_METHOD_0(int, QuestQuery, GetQuestAcceptNum);
DECLARE_METHOD_1(bool, QuestQuery, GetQuestIsStep, int);

DECLARE_METHOD_1(bool, QuestQuery, GetQuestIsTimeLimit, int);

DECLARE_METHOD_1(bool, QuestQuery, GetQuestCanGiveUp, int);
DECLARE_METHOD_1(bool, QuestQuery, GetQuestCanLibertySubmit, int);
DECLARE_METHOD_1(int, QuestQuery, GetQuestStep, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetAcceptNpc, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetSubmitNpc, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetAcceptArea, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetSubmitArea, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetCompleteInfo, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetUnCompleteInfo, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetHideStep, int);
DECLARE_METHOD_1(bool, QuestQuery, CanAcceptQuest, int);
//是否和自己的种族符合脚本接口 by add lizy
DECLARE_METHOD_T(QuestQuery, GetQuestTrackInfo);

DECLARE_METHOD_T(QuestQuery, GetCriteriaList);

DECLARE_METHOD_1(bool, QuestQuery, IsUseCustomCriteriaTrackInfo, int);
DECLARE_METHOD_T(QuestQuery, GetCustomCriteriaTrackInfoPos)

DECLARE_METHOD_1(int, QuestQuery, GetCriteriaType, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetCriteriaArea, int);
DECLARE_METHOD_1(int, QuestQuery, GetCriteriaState, int);
DECLARE_METHOD_1(int, QuestQuery, GetCriteriaQuestID, int);
DECLARE_METHOD_1(int, QuestQuery, GetCriteriaID, int);
DECLARE_METHOD_T(QuestQuery, GetCriteriaProgList);
DECLARE_METHOD_T(QuestQuery, GetCriteriaHyperlinkInfo);
DECLARE_METHOD_1(const char*, QuestQuery, GetCriteriaParentTitle, int);

//任务超链接接口
DECLARE_METHOD_T(QuestQuery, GetCriteriaHyperlinkInfobyhyper);

DECLARE_METHOD_1(std::string, QuestQuery, GetCriteriaTrackInfo, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetCriteriaTalkDialog, int);
DECLARE_METHOD_T(QuestQuery, GetCriteriaTalkRecoverItems);
DECLARE_METHOD_T(QuestQuery, GetCriteriaTalkGiveItems);
DECLARE_METHOD_1(int, QuestQuery, GetCriteriaAwardID, int);

//增加脚本获得收集道具接口 by add lizy
DECLARE_METHOD_T(QuestQuery, GetCriteriaTalkCollectItems);

DECLARE_METHOD_2(std::string, QuestQuery, GetItemSrcPos, const char*, const char*);
DECLARE_METHOD_0(int, QuestQuery, GetMainPlayerCamp);
DECLARE_METHOD_0(int, QuestQuery, GetMainPlayerLevel);
DECLARE_METHOD_0(int, QuestQuery, GetMainPlayerAutoQuest);


DECLARE_METHOD_1(bool, QuestQuery, IsSeriesQuest, int);
DECLARE_METHOD_1(bool, QuestQuery, GetSeriesQuestHide, int);
//DECLARE_METHOD_1(bool, QuestQuery, GetSeriesQuestLast, int);
DECLARE_METHOD_1(bool, QuestQuery, GetSeriesAbility, const char*);
DECLARE_METHOD_2(bool, QuestQuery, IsSeriesFirstQuest, const char*, int);
DECLARE_METHOD_1(bool, QuestQuery, IsSeriesLastQuest, int);

DECLARE_METHOD_T(QuestQuery, GetSeriesFirstQuest);
DECLARE_METHOD_T(QuestQuery, GetSeriesLastQuest);
DECLARE_METHOD_1(std::string, QuestQuery, GetQuestSeries, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetSeriesQuestParent, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetSeriesTitleDes, const char*);
DECLARE_METHOD_1(bool, QuestQuery, InitSeriesQuestOpend, const char*);
DECLARE_METHOD_1(bool, QuestQuery, GetSeriesQuestOpend, int);
DECLARE_METHOD_1(int, QuestQuery, GetSeriesEffectQuest, const char*);

DECLARE_METHOD_2(bool, QuestQuery, SetSeriesQuestOpend, int, bool);
DECLARE_METHOD_3(int, QuestQuery, GetSeriesQuestByPos, const char*, int, int);
DECLARE_METHOD_1(std::string, QuestQuery, GetSeriesQuestChildStr, int);
DECLARE_METHOD_T(QuestQuery, GetSeriesQuestChildList);
DECLARE_METHOD_T(QuestQuery, GetEffectSeriesList);
DECLARE_METHOD_T(QuestQuery, GetSeriesQuestBrotherList);

DECLARE_METHOD_T(QuestQuery, GetSeriesQuestGridPoints);

//新任务日志
DECLARE_METHOD_T(QuestQuery, GetSeriesEffectQuestList);
DECLARE_METHOD_1(int, QuestQuery, GetSeriesSortProp, const char*);


DECLARE_METHOD_1(bool, QuestQuery, RefreshNpcQuestEffect, const PERSISTID&);
DECLARE_METHOD_1(bool, QuestQuery, HideNpcQuestEffect,  const PERSISTID&);
DECLARE_METHOD_1(bool, QuestQuery, IsNpcHaveQuest, const char*);
DECLARE_METHOD_1(const char*, QuestQuery, GetNpcQuestFlagEffect,  const char*);
DECLARE_METHOD_1(const char*, QuestQuery, GetNpcQuestFlagImage,  const char*);
DECLARE_METHOD_1(int, QuestQuery, GetNpcQuestFlag,  const char*);

DECLARE_METHOD_T(QuestQuery, GetAllBranchQuestIDList);
DECLARE_METHOD_T(QuestQuery, GetBranchQuestIDList);
DECLARE_METHOD_1(bool, QuestQuery, IsNpcSatisfyGather,  const char*);

DECLARE_METHOD_T(QuestQuery, GetNpcSatisfyInterQuestMenus);
DECLARE_METHOD_T(QuestQuery, GetDoingQuestMenus);
DECLARE_METHOD_T(QuestQuery, GetAcceptQuestMenus);
DECLARE_METHOD_T(QuestQuery, GetSubmitQuestMenus);

DECLARE_METHOD_1(bool, QuestQuery, CanPickQuestItem, const char*);

DECLARE_METHOD_T(QuestQuery, GetRecommendAreaList);
DECLARE_METHOD_T(QuestQuery, GetRecommendQuestIDList);

DECLARE_METHOD_1(bool, QuestQuery, IsNpcSatisfyAccept, const char*);
DECLARE_METHOD_1(bool, QuestQuery, IsNpcSatisfySubmit, const char*);
DECLARE_METHOD_1(bool, QuestQuery, IsNpcSatisfyUnComplete, const char*);

// ================================
// 主线任务相关
// ================================
DECLARE_METHOD_0(int, QuestQuery, GetCurrentMainQuestID);
DECLARE_METHOD_0(int, QuestQuery, GetNextMainQuestID);
DECLARE_METHOD_T(QuestQuery, GetRewardedMainQuestList);
DECLARE_METHOD_1(bool, QuestQuery, IsCriteriaVisibleInTrace, int);
DECLARE_METHOD_1(bool, QuestQuery, IsCriteriaTalkWithFunc, int);


const char* quest_rec            = "QuestRecord";                // 任务进度表
const char* quest_rewarded_rec    = "QuestRewarded";                // 任务完成表
const char* quest_criteria_rec    = "QuestCriteriaRecord";        // 任务子模板进度表
const char* quest_timelimit_rec = "QuestTimeLimitRecord";        // 任务时间限制
const char* quest_drop_rec        = "QuestDropRecord";            // 任务道具掉落表    
const char* quest_hidenpc_rec    = "QuestHideRecord";            // 任务隐藏相关NPC
const char* quest_onloadfail_rec= "Quest_Fail_OnLoad_Rec";        // 任务上线失败记录表
const char* repeat_quest_rec    = "QuestRepeatRecord";            // 日常周常表
const char* quest_series_rec    = "QuestSeriesRecord";            // 任务系列表
const char* quest_can_accept    = "QuestCanAccept";                // NPC身上可接受任务表
const char* quest_can_submit    = "QuestCanSubmit";                // NPC身上可提交任务表

const int ACCEPT_QUEST_MAXNUM    = 25;                            // 最大可接任务数
const int TRACK_QUEST_MAXNUM    = 10;                            // 最大可接任务数
const float QUEST_SHARE_DIST    = 50.0f;                        // 任务共享半径
const float QUEST_RANDOM_DIST   = 1.0f;
const int QUEST_TO_ACCEPT_LEVEL = 2;                            // 可查看任务等级差

QuestQuery::QuestQuery()
{

}

// 析构函数
QuestQuery::~QuestQuery()
{
    ReleaseResource();
}

// 初始化
bool QuestQuery::Init(const IVarList& args)
{
    LoadResource();
    return true;
}

bool QuestQuery::Shut()
{
    // 清理资源
    ReleaseResource();
    return true;
}

void QuestQuery::LoadResource()
{
    const char* workpath = GetCore()->GetResourcePath();

    if (NULL == workpath)
    {
        return;
    }

    QuestBaseData::instance().LoadRes(this, workpath);
    QuestCriteriaData::instance().LoadRes(workpath);
    LoadNpcQuestFlagRes(workpath);
}

void QuestQuery::ReleaseResource()
{
    QuestBaseData::instance().ReleaseRes();
    QuestCriteriaData::instance().ReleaseRes();
    QuestSeriesData::instance().ReleaseRes();
    ReleaseNpcQuests();
    ReleaseNpcQuestFlagRes();
}

bool QuestQuery::LoadNpcQuestFlagRes(const char* work_path)
{
    std::string path = work_path;

    ReleaseNpcQuestFlagRes();
    path += "ini/NpcFlag/QuestFlag.xml";
    CXmlFile xml(path.c_str());
    if (!xml.LoadFromFile())
    {
        ConsoleLog("QuestQuery", "load %s failed!", path.c_str());
        return false;
    }

    CVarList sec_list;
    xml.GetSectionList(sec_list);
    for (size_t i = 0; i < sec_list.GetCount(); i++)
    {
        const char* sec_name = sec_list.StringVal(i);
        if (NULL == sec_name)
        {
            continue;
        }

        // 段名id
        int sec_id = atoi(sec_name);

        std::map<int, NpcQuestFlagRes*>::iterator iter = m_npc_questflags_map.find(sec_id);

        // 已经初始化了
        if (iter != m_npc_questflags_map.end())
        {
            continue;
        }

        NpcQuestFlagRes* flag = CORE_NEW(NpcQuestFlagRes);
        flag->effect_flag = xml.ReadString(sec_name, "Effect", "");
        flag->image_flag = xml.ReadString(sec_name, "Image", "");

        m_npc_questflags_map[sec_id] = flag;
    }

    return true;
}

bool QuestQuery::LoadNpcQuests(int nQuestID, const char* sAcceptNpc, const char* sSubmitNpc)
{
    if (strcmp(sAcceptNpc,"") != 0)
    {//插入可接受任务NPC
        std::map<std::string, NpcQuests*>::iterator IterAcceptNpc = m_npc_quests_map.find(sAcceptNpc);
        if (IterAcceptNpc != m_npc_quests_map.end())
        {
            NpcQuests* pNpcQuest = IterAcceptNpc->second;
            pNpcQuest->canAcceptQuests.push_back(nQuestID);
        }
        else
        {
            NpcQuests* npc_quest_temp = CORE_NEW(NpcQuests);
            npc_quest_temp->canAcceptQuests.push_back(nQuestID);
            m_npc_quests_map[sAcceptNpc] = npc_quest_temp;
        }
    }

    if (strcmp(sAcceptNpc,"") != 0)
    { //插入提交任务NPC
        std::map<std::string, NpcQuests*>::iterator IterSubmitNpc = m_npc_quests_map.find(sSubmitNpc);
        if (IterSubmitNpc != m_npc_quests_map.end())
        {
            NpcQuests* pNpcQuest = IterSubmitNpc->second;
            pNpcQuest->canSubmitQuests.push_back(nQuestID);
        }
        else
        {
            NpcQuests* npc_quest_temp = CORE_NEW(NpcQuests);
            npc_quest_temp->canSubmitQuests.push_back(nQuestID);
            m_npc_quests_map[sSubmitNpc] = npc_quest_temp;
        }
    }

    return true;
}

bool QuestQuery::ReleaseNpcQuests()
{
    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.begin();
    for (; iter != m_npc_quests_map.end(); ++iter)
    {
        if (iter->second != NULL)
        {
            CORE_DELETE(iter->second);
        }
    }
    m_npc_quests_map.clear();
    return true;
}

bool QuestQuery::ReleaseNpcQuestFlagRes()
{
    std::map<int, NpcQuestFlagRes*>::iterator iter = m_npc_questflags_map.begin();
    for (; iter != m_npc_questflags_map.end(); ++iter)
    {
        if (iter->second != NULL)
        {
            CORE_DELETE(iter->second);
        }
    }
    m_npc_questflags_map.clear();
    return true;
}

// 获得主角玩家网络对象
IGameObject* QuestQuery::GetMainPlayer()
{
    // 客户端相关对象
    ICore* pCore = this->GetCore();

    PERSISTID game_client_id = pCore->GetGlobalValue("game_client").ObjectVal();

    IGameClient* pGameClient = (IGameClient*)pCore->GetEntity(game_client_id);

    if (NULL == pGameClient)
    {
        return NULL;
    }

    // 主角玩家网络对象
    const PERSISTID player_client = pGameClient->GetPlayer();

    IGameObject* pClientPlayer = (IGameObject*)GetCore()->GetEntity(player_client);

    return pClientPlayer;
}

int QuestQuery::GetLevel()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return 0;
    }

    if (pClientPlayer->FindProp("Level"))
    {
        return 0;
    }

    return pClientPlayer->QueryPropInt("Level");
}

//追踪列表
size_t QuestQuery::GetTrackList(const IVarList& args, IVarList& result)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        size_t record_count = pClientPlayer->GetRecordRows(quest_rec);

        for(size_t i=0; i<record_count; ++i)
        {
            int quset_id = pClientPlayer->QueryRecordInt(quest_rec, i, QUEST_REC_ID);

            int track = pClientPlayer->QueryRecordInt(quest_rec, i, QUEST_REC_TRACK);
            if (track > 0)
            {
                result.AddInt(quset_id);
            }
        }
    }

    return result.GetCount();
}


const char* QuestQuery::GetAcceptNpc(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetAcceptNpc();
    }

    return "";
}

const char* QuestQuery::GetSubmitNpc(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetSubmitNpc();
    }

    return "";
}


const char* QuestQuery::GetAcceptArea(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetAcceptArea();
    }

    return "";
}

const char* QuestQuery::GetSubmitArea(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetSubmitArea();
    }

    return "";
}

const char* QuestQuery::GetCompleteInfo(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetCompleteInfo();
    }

    return "";
}


const char* QuestQuery::GetUnCompleteInfo(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetUnCompleteInfo();
    }

    return "";
}

const char* QuestQuery::GetHideStep(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetHideStep();
    }

    return "1,1,1";
}

int QuestQuery::GetQuestID(int row_num)
{
    if (row_num >= 0)
    {
        IGameObject* pClientPlayer = GetMainPlayer();

        if (NULL == pClientPlayer)
        {
            return -1;
        }


        if (pClientPlayer->FindRecord(quest_rec))
        {
            int quset_id = pClientPlayer->QueryRecordInt(quest_rec, row_num, QUEST_REC_ID);

            return quset_id;
        }
    }

    return -1;
}

const char* QuestQuery::GetQuestTitle(int quest_id) const
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetTitle();
    }

    return "";
}

const char* QuestQuery::GetQuestObj(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetObjectives();
    }

    return "";
}

const char* QuestQuery::GetQuestDetails(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        return quest_wrap.GetDetails();
    }

    return "";
}


int QuestQuery::GetQuestAwardID(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int award_id = quest_wrap.GetAward();

        if (award_id > 0)
        {
            return award_id;
        }

    }

    return -1;
}

const char *QuestQuery::GetCriteriaUseItemID(int criteria_id)
{
    QuestCriteriaWrap criteria(criteria_id);
    if (!criteria.IsValid())
    {
        return "";
    }

    if (criteria.GetType() == QUEST_CRITERIA_TYPE_USEITEM_AREA)
    {
        return (*criteria.GetUseItemArea().use_item).c_str();
    }
    else if (criteria.GetType() == QUEST_CRITERIA_TYPE_USEITEM_LOCKTARGET)
    {
        return (*criteria.GetUseItemLock().use_item).c_str();
    }

    return "";
}

int QuestQuery::GetQuestType(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int quest_type = quest_wrap.GetType();

        if (quest_type > 0)
        {
            return quest_type;
        }

    }

    return -1;
}

int QuestQuery::GetAcceptType(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int quest_type = quest_wrap.GetAcceptType();

        if (quest_type > 0)
        {
            return quest_type;
        }
    }
    return 1;
}


int QuestQuery::GetQuestTimeType(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int time_type = quest_wrap.GetTimeRepeatType();

        return time_type;
    }

    return 0;  
}


bool QuestQuery::GetQuestCanShare(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        bool can_share = quest_wrap.CanShare();

        return can_share;
    }

    return false;
}


int QuestQuery::GetQuestLevel(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int quest_level = quest_wrap.GetQuestLevel();

        return quest_level;
    }

    return 0;  
}

int QuestQuery::GetQuestMinLevel(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        int quest_min_level = quest_wrap.GetMinLevel();

        return quest_min_level;
    }

    return -1;  
}

int QuestQuery::GetQuestState(int quest_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return QUEST_STATUS_NONE;
    }

    if (pClientPlayer->FindRecord(quest_rewarded_rec))
    {
        //所处行数
        int row = quest_id/32;
        //位移量
        int bit_count = quest_id%32;

        //获取任务编号位集
        long data = pClientPlayer->QueryRecordInt(quest_rewarded_rec, row, 0);

        int bit = (data>>(bit_count))&1;

        if (bit == 1)
        {
            return QUEST_STATUS_REWARDED;
        }

    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_rec << QUEST_REC_ID << quest_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {

            return QUEST_STATUS_NONE;
        }

        int state = pClientPlayer->QueryRecordInt(quest_rec, row, QUEST_REC_STATUS);

        //完成表

        return state;

    }


    return QUEST_STATUS_NONE;
}


int QuestQuery::GetQuestTrackIndex(int quest_id)
{
    CVarList result;
    GetTrackList(CVarList(), result);

    size_t result_count = result.GetCount();
    int quest_index = 1;

    //判断是否可追踪(任务的追踪目标是否无法查询到具体的位置信息)


    //遍历追踪顺序
    for (size_t i=0; i<result_count; ++i)
    {
        //追踪列表中依次取出任务比较
        int quest = result.IntVal(i);

        //任务状态有:正在进行、以失败、可提交、已提交
        int state = GetQuestState(quest);

        if (quest == quest_id)
        {
            if (state == QUEST_CRITERIA_STATUS_DOING || state == QUEST_CRITERIA_STATUS_FAILED)
            {
                return quest_index;            
            }
            else
            {
                //任务完成
                return 0;
            }
        }
        else
        {
            if (state == QUEST_CRITERIA_STATUS_DOING || state == QUEST_CRITERIA_STATUS_FAILED)
            {
                quest_index += 1;
            }
        }
    }


    //任务不可追踪状态
    return -1;
}


int QuestQuery::GetQuestTrackState(int quest_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return 0;
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_rec << QUEST_REC_ID << quest_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return 0;
        }

        int track_state = pClientPlayer->QueryRecordInt(quest_rec, row, QUEST_REC_TRACK);

        return track_state;

    }

    return 0;
}


int QuestQuery::GetQuestAcceptNum()
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return 0;
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        int row = pClientPlayer->GetRecordRows(quest_rec);

        return row;
    }

    return 0;
}


bool QuestQuery::GetQuestCanLibertySubmit(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        if (quest_wrap.CanLibertySubmit())
        {
            return true;
        }     
    }

    return false;
}

bool QuestQuery::GetQusetIsSpecialHide(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        if (quest_wrap.IsSpecialHide())
        {
            return true;
        }     
    }

    return false;
}


size_t QuestQuery::GetQuestTrackInfo(const IVarList& args, IVarList& result)
{
    int quest_id = args.IntVal(0);

    int quest_state = GetQuestState(quest_id);

    if (QUEST_STATUS_CANSUBMIT == quest_state)
    {
        std::string submit_area = GetSubmitArea(quest_id);
        std::string submit_npc = GetSubmitNpc(quest_id);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "%d;findnpc;%s;%s;%s", -1, submit_area.c_str(), submit_npc.c_str(), "");

        result.AddString(key);
    }
    else
    {
        CVarList result_criteria;
        size_t criteria_count = GetCriteriaList(CVarList()<<quest_id, result_criteria);

        for (size_t i=0; i<criteria_count; ++i)
        {
            int criteria_id = result_criteria.IntVal(i);

            QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria_id);
            if (!quest_criteria_wrap.IsValid())
            {
                continue;
            }

            int criteria_state = GetCriteriaState(criteria_id);
            if (criteria_state == QUEST_CRITERIA_STATUS_COMPLETED)
            {
                continue;
            }

            //子模板区域信息
            std::string area_name = GetCriteriaArea(criteria_id);

            //子模板类型
            int criteria_type = GetCriteriaType(criteria_id);

            //击杀类
            if (criteria_type == QUEST_CRITERIA_TYPE_KILL_NPC)
            {
                CriteriaDataKillNPC criteria_kill = quest_criteria_wrap.GetKillNpc();

                StrList* npc_list = criteria_kill.kill_npc_list;

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                StrList::iterator it_vec = (*npc_list).begin();
                for (; it_vec!=(*npc_list).end(); ++it_vec)
                {
                    std::string npc = *it_vec;

                    if (key[0] == 0)
                    {
                        SafeSprintf(key, sizeof(key), "%d;findnpc;%s;%s", criteria_id, area_name.c_str(), npc.c_str() );
                    }
                    else
                    {
                        SafeSprintf(key, sizeof(key), "%s,%s", key, npc.c_str() );  
                    }                  
                }

                SafeSprintf(key, sizeof(key), "%s;%s", key, "");

                result.AddString(key);
            }


            //对话类
            else if (criteria_type == QUEST_CRITERIA_TYPE_TALK)
            {
                CriteriaDataTalk criteria_talk = quest_criteria_wrap.GetTalk();

                std::string npc = *(criteria_talk.npc_id);

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                SafeSprintf(key, sizeof(key), "%d;findnpc;%s;%s;%s", criteria_id, area_name.c_str(), npc.c_str(), "");

                result.AddString(key);

            }


            //锁定目标(npc)使用物品类
            else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_LOCKTARGET)
            {
                CriteriaDataUseItemLock criteria_lockuse = quest_criteria_wrap.GetUseItemLock();

                std::string target = *(criteria_lockuse.target_npc);
                std::string use_item = *(criteria_lockuse.use_item);

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                SafeSprintf(key, sizeof(key), key, "%d;findnpc;%s;%s;%s",
                    criteria_id, area_name.c_str(), target.c_str(), use_item.c_str());

                result.AddString(key);

            }


            //区域使用物品类
            else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_AREA)
            {
                CriteriaDataUseItemArea criteria_usearea = quest_criteria_wrap.GetUseItemArea();

                std::string use_item = *(criteria_usearea.use_item);
                float pos_x = criteria_usearea.x;
                float pos_y = criteria_usearea.y;
                float pos_z = criteria_usearea.z;

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                SafeSprintf(key, sizeof(key), "%d;findpos;%s;%f,%f,%f;%s",  
                    criteria_id, area_name.c_str(), pos_x, pos_y, pos_z, use_item.c_str());

                result.AddString(key);

            }

            //采集物品类
            else if (criteria_type == QUEST_CRITERIA_TYPE_COLLECT_ITEM)
            {
                CriteriaDataCollectItem criteria_collect = quest_criteria_wrap.GetCollectItem();

                StrList* npc_list = criteria_collect.flop_npc_list;

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                SafeSprintf(key, sizeof(key), "%d;findnpc;%s;", criteria_id, area_name.c_str());

                std::string info = key;

                StrList::iterator it_vec = (*npc_list).begin();
                for (; it_vec!=(*npc_list).end(); ++it_vec)
                {

                    std::string npc = *it_vec;

                    /* if (key[0] == 0)
                    {
                    sprintf( key, "%d;findnpc;%s;%s", criteria_id, area_name.c_str(), npc.c_str() );
                    }
                    else
                    {
                    sprintf( key, "%s,%s", key, npc.c_str() );  
                    }     */


                    if (it_vec + 1 == (*npc_list).end())
                    {
                        info = info + npc.c_str() + "; ";
                    }
                    else
                    {
                        info = info + npc.c_str() + ",";
                    }

                }

                //sprintf( key, "%s;%s", key, "");

                result.AddString(info.c_str());
            }
            else
            {    

                if (!IsUseCustomCriteriaTrackInfo(criteria_id))
                {
                    return result.GetCount();
                }

                CustomCriteriaTrackInfo& custom_criteria_track_info = quest_criteria_wrap.GetCustomTrackInfo();

                int pos_x = custom_criteria_track_info.pos_x;
                int pos_y = custom_criteria_track_info.pos_y;
                int pos_z = custom_criteria_track_info.pos_z;

                char key[128] = { 0 };
                //memset(key, 0, sizeof(key));

                SafeSprintf(key, sizeof(key), "%d;findpos;%s;%d,%d,%d;%s",  
                    criteria_id, area_name.c_str(), pos_x, pos_y, pos_z, "");

                result.AddString(key);

            }


        }
    }

    return result.GetCount();
}


bool QuestQuery::GetQuestIsStep(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        if (quest_wrap.IsStep())
        {
            return true;
        }
    }

    return false;
}
bool QuestQuery::GetQuestIsTimeLimit(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        if (quest_wrap.IsTimeLimit())
        {
            return true;
        }
    }

    return false;
}

int QuestQuery::GetLimitedTime(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        if (quest_wrap.IsTimeLimit())
        {
            return quest_wrap.GetTimeLimit();
        }
    }

    return 0;
}

bool QuestQuery::GetQuestCanGiveUp(int quest_id)
{
    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        bool can_give_up = quest_wrap.CanGiveUp();
        return can_give_up;
    }

    //默认可放弃
    return true;
}

int QuestQuery::GetQuestStep(int quest_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return -1;
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_rec << QUEST_REC_ID << quest_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return -1;
        }

        int step = pClientPlayer->QueryRecordInt(quest_rec, row, QUEST_REC_STEP_CRITERIA_ID);

        return step;

    }

    return -1;


}

size_t QuestQuery::GetCriteriaList(const IVarList& args, IVarList& result)
{
    int quest_id = args.IntVal(0);

    QuestWrap quest_wrap = QuestWrap(quest_id);

    if (quest_wrap.IsValid())
    {
        const NumberList& pNumberList = quest_wrap.GetCriteriaList();

        for (int i = 0; i < (int)pNumberList.size(); ++i)
        {
            int criteria = pNumberList[i];
            result.AddInt(criteria);
        }

    }

    return result.GetCount();
}


int QuestQuery::GetCriteriaID(int row_num)
{
    if (row_num >= 0)
    {
        IGameObject* pClientPlayer = GetMainPlayer();
        if (NULL == pClientPlayer)
        {
            return -1;
        }

        if (pClientPlayer->FindRecord(quest_criteria_rec))
        {
            int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec, row_num, QUEST_CRITERIA_REC_CRITERIA_ID);

            return criteria_id;
        }
    }

    return -1;

}


//任务子模板类型
int QuestQuery::GetCriteriaType(int criteria)
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);

    if (quest_criteria_wrap.IsValid())
    {
        return quest_criteria_wrap.GetType();
    }

    return -1;
}

const char* QuestQuery::GetCriteriaArea(int criteria)
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);

    if (quest_criteria_wrap.IsValid())
    {
        return quest_criteria_wrap.GetAreaID();
    }

    return "";
}

bool QuestQuery::IsUseCustomCriteriaTrackInfo(int criteria)
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);

    if (!quest_criteria_wrap.IsValid())
    {
        return false;
    }

    CustomCriteriaTrackInfo& custom_criteria_track_info = quest_criteria_wrap.GetCustomTrackInfo();

    bool track_flag = custom_criteria_track_info.track_flag;

    return track_flag;
}


size_t QuestQuery::GetCustomCriteriaTrackInfoPos(const IVarList& args, IVarList& result)
{
    int criteria = args.IntVal(0);

    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);

    if (!quest_criteria_wrap.IsValid())
    {
        return result.GetCount();
    }

    CustomCriteriaTrackInfo& custom_criteria_track_info = quest_criteria_wrap.GetCustomTrackInfo();

    float pos_x = custom_criteria_track_info.pos_x;
    float pos_y = custom_criteria_track_info.pos_y;
    float pos_z = custom_criteria_track_info.pos_z;

    result << pos_x << pos_y << pos_z;

    return result.GetCount();

}


int QuestQuery::GetCriteriaState(int criteria)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return -1;
    }

    if (pClientPlayer->FindRecord(quest_criteria_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_criteria_rec << QUEST_CRITERIA_REC_CRITERIA_ID << criteria << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return -1;
        }

        int state = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_STATUS);

        return state;

    }


    return -1;
}

//任务子模板进度表
size_t QuestQuery::GetCriteriaProgList(const IVarList& args, IVarList& result)
{
    int criteria = args.IntVal(0);

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }


    if (pClientPlayer->FindRecord(quest_criteria_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_criteria_rec << QUEST_CRITERIA_REC_CRITERIA_ID << criteria << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return result.GetCount();
        }

        int cur_num = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_CURNUM);
        int max_num = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_MAXNUM);

        result.AddInt(cur_num);
        result.AddInt(max_num);

    }

    return result.GetCount();
}

const char *QuestQuery::GetCriteriaTrackInfo(int criteria_id) const
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria_id);
    if (quest_criteria_wrap.IsValid())
    {
        return quest_criteria_wrap.GetTrackInfo();
    }

    return "";
}

int QuestQuery::GetCriteriaAwardID(int criteria_id)
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria_id);

    if (!quest_criteria_wrap.IsValid())
    {
        return 0;        
    }
    return quest_criteria_wrap.GetCriteriaAwardID();
}

const char* QuestQuery::GetCriteriaParentTitle(int criteria_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return "";
    }


    if (pClientPlayer->FindRecord(quest_criteria_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_criteria_rec << QUEST_CRITERIA_REC_CRITERIA_ID << criteria_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return "";
        }

        int parent_type = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_PARENT_TYPE);
        int parent_id = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_PARENT_ID);

        if (parent_type == CRITERIA_PARENT_QUEST)
        {
            QuestWrap quest(parent_id);
            if (quest.IsValid())
            {
                return quest.GetTitle();
            }
        }
        else if (parent_type == CRITERIA_PARENT_EVENT)
        {
            SceneTrigger* pST = (SceneTrigger*)CHelper::GetGlobalEntity("scenetrigger");
            if (pST)
            {
                CVarList res;
                pST->GetTextIdList(CVarList()<<parent_id, res);
                return res.StringVal(0);
            }
        }
    }

    return "";
}


int QuestQuery::GetCriteriaQuestID(int criteriia_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return -1;
    }


    if (pClientPlayer->FindRecord(quest_criteria_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_criteria_rec << QUEST_CRITERIA_REC_CRITERIA_ID << criteriia_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return -1;
        }

        int quest_id = pClientPlayer->QueryRecordInt(quest_criteria_rec, row, QUEST_CRITERIA_REC_PARENT_ID);


        return quest_id;
    }

    return -1;

}


//返回的表数据中包括SceneID、NpcList、ItemID、AreaPoints数据项,根据模板类型不同提取不同数据处理,任务可提交时仅返回提交npc
size_t QuestQuery::GetCriteriaHyperlinkInfo(const IVarList& args, IVarList& result)
{
    int criteria = args.IntVal(0);

    int criteria_type = GetCriteriaType(criteria);

    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);
    if (!quest_criteria_wrap.IsValid())
    {
        return result.GetCount();
    }

    //模板所属任务
    int quest_id = GetCriteriaQuestID(criteria);
    //区域名称
    std::string area_name = "";

    //所属任务状态
    GetQuestState(quest_id);

    //记录场景信息
    int scene_id = -1;

    //任务完成前后子模板需显示的信息不同
    //if (state == QUEST_STATUS_CANSUBMIT)
    //{
    //    //提交任务npc
    //    std::string submit_npc = GetSubmitNpc(quest_id);

    //    if (submit_npc != "")
    //    {
    //        char key[128] = { 0 };
    //        //memset(key, 0, sizeof(key));

    //        SafeSprintf(key, sizeof(key), "NpcList=%s", submit_npc.c_str() );

    //        result.AddString(key);
    //    }

    //    //查询任务提交npc所在场景信息
    //    //区域信息
    //    area_name = GetSubmitArea(quest_id);
    //    if (area_name != "")
    //    {
    //        char key[128] = { 0 };
    //        //memset(key, 0, sizeof(key));

    //        SafeSprintf(key, sizeof(key), "AreaName=%s", area_name.c_str() );

    //        result.AddString(key);
    //    }
    //}
    //else
    //{
    //击杀类
    if (criteria_type == QUEST_CRITERIA_TYPE_KILL_NPC)
    {
        CriteriaDataKillNPC criteria_kill = quest_criteria_wrap.GetKillNpc();

        StrList* npc_list = criteria_kill.kill_npc_list;

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        StrList::iterator it_vec = (*npc_list).begin();
        for (; it_vec!=(*npc_list).end(); ++it_vec)
        {
            std::string npc = *it_vec;

            if (key[0] == 0)
            {
                SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str() );
            }
            else
            {
                SafeSprintf(key, sizeof(key), "%s,%s", key, npc.c_str() );  
            }

        }

        result.AddString(key);
    }


    //对话类
    else if (criteria_type == QUEST_CRITERIA_TYPE_TALK)
    {
        CriteriaDataTalk criteria_talk = quest_criteria_wrap.GetTalk();

        std::string npc = *(criteria_talk.npc_id);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str() );

        result.AddString(key);

    }


    //锁定目标(npc)使用物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_LOCKTARGET)
    {
        CriteriaDataUseItemLock criteria_lockuse = quest_criteria_wrap.GetUseItemLock();

        std::string target = *(criteria_lockuse.target_npc);
        std::string use_item = *(criteria_lockuse.use_item);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "NpcList=%s", target.c_str() );

        result.AddString(key);
        memset(key, 0, sizeof(key));
        SafeSprintf(key, sizeof(key), "ItemID=%s", use_item.c_str() );

        result.AddString(key);

    }


    //区域使用物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_AREA)
    {
        CriteriaDataUseItemArea criteria_usearea = quest_criteria_wrap.GetUseItemArea();

        scene_id = criteria_usearea.scene_id;
        std::string use_item = *(criteria_usearea.use_item);
        float pos_x = criteria_usearea.x;
        float pos_y = criteria_usearea.y;
        float pos_z = criteria_usearea.z;

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "ItemID=%s", use_item.c_str() );

        result.AddString(key);
        memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "AreaPoints=%f,%f,%f", pos_x, pos_y, pos_z );

        result.AddString(key);

    }

    //搜集物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_COLLECT_ITEM)
    {
        CriteriaDataCollectItem criteria_collect = quest_criteria_wrap.GetCollectItem();

        StrList* npc_list = criteria_collect.flop_npc_list;
        std::string collect_item = *(criteria_collect.collect_item);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));
        StrList::iterator it_vec = (*npc_list).begin();
        for (; it_vec != (*npc_list).end(); ++it_vec)
        {
            std::string npc = *it_vec;
            if (key[0] == 0)
            {
                SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str());
            }
            else
            {
                SafeSprintf(key, sizeof(key), "%s,%s", key, npc.c_str());  
            }
        }
        result.AddString(key);

        memset(key, 0, sizeof(key));
        SafeSprintf(key, sizeof(key), "ItemID=%s", collect_item.c_str());
        result.AddString(key);
    }
    //通关副本类
    else if(criteria_type == QUEST_CRITERIA_TYPE_CLONE_COMPLETE)
    {
        CriteriaDataCloneComplete criteria_cloneComplete = quest_criteria_wrap.GetCloneCompleteData();
        int clone_id = criteria_cloneComplete.clone_id;
        //int clone_diffeculty = criteria_cloneComplete.clone_difficulty;
        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));
        //sprintf( key, "CloneID=%s, CloneDifficult=%s", clone_id.c_str(), clone_diffeculty);
        SafeSprintf(key, sizeof(key), "CloneID=%d", clone_id);

        result.AddString(key);
    }


    //区域信息
    area_name = GetCriteriaArea(criteria);
    if (area_name != "")
    {
        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "AreaName=%s", area_name.c_str() );

        result.AddString(key);
    }
    //}


    if (scene_id > 0)
    {
        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "SceneID=%d", scene_id);

        result.AddString(key);
    }

    return result.GetCount();
}


const char* QuestQuery::GetItemSrcPos(const char* view_indent, const char* item_config)
{
    // 客户端相关对象
    ICore* pCore = this->GetCore();

    PERSISTID game_client_id = pCore->GetGlobalValue("game_client").ObjectVal();

    IGameClient* pGameClient = (IGameClient*)pCore->GetEntity(game_client_id);
    if (NULL == pGameClient)
    {
        return "";
    }

    PERSISTID view_obj = pGameClient->GetView(view_indent);
    if (view_obj.IsNull())
    {
        return "";
    }

    IGameObject* pViewObj = (IGameObject*)GetCore()->GetEntity(view_obj);
    if (NULL == pViewObj)
    {
        return "";
    }

    CVarList result;

    pViewObj->GetViewObjList(CVarList(), result);

    size_t count = result.GetCount();

    for (size_t i=0; i<count; ++i)
    {
        PERSISTID item_obj = result.ObjectVal(i);

        IGameObject* pViewItem = (IGameObject*)GetCore()->GetEntity(item_obj);
        if (NULL == pViewItem)
        {
            return "";
        }

        // 查询配置名
        const char* config = pViewItem->QueryPropString("ConfigID");

        if (strcmp(config, item_config) == 0)
        {
            // 查找成功,跳出
            return pViewItem->GetIdent();
            //return std::string(ident);
        }
    }

    return "0";

}

const char* QuestQuery::GetMainPlayerName()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return "";
    }

    const char* player_name = pClientPlayer->QueryPropString("Name");

    return player_name;
}


int QuestQuery::GetMainPlayerCamp()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return -1;
    }

    int camp = pClientPlayer->QueryPropInt("Camp");

    return camp;
}

int QuestQuery::GetMainPlayerLevel()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return -1;
    }


    int level = pClientPlayer->QueryPropInt("Level");

    return level;
}

int QuestQuery::GetMainPlayerRoleIndex()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return -1;
    }


    int roleIndex = pClientPlayer->QueryPropInt("RoleIndex");
    return roleIndex;
}

bool QuestQuery::GetMainPlayerAutoQuest()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    int auto_quest_flag = pClientPlayer->QueryPropInt("AutoQuestFlag");

    if (auto_quest_flag == 1)
    {
        return true;
    }

    return false;
}

bool QuestQuery::IsSeriesQuest(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        return true;
    }

    return false;
}


const char* QuestQuery::GetQuestSeries(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        std::string series_id = series_quest_wrap.GetSeriesID();

        return series_id.c_str();
    }

    return "";
}


const char* QuestQuery::GetSeriesQuestParent(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        std::string parent_id = series_quest_wrap.GetParent();

        int parent_quest = ::atoi(parent_id.c_str());
        if(parent_quest == quest_id)
        {
            ConsoleLog("QuestQuery", "警告:任务ID与父任务ID一样(%d)", quest_id);
            return "";
        }

        return parent_id.c_str();
    }

    return "";
}


size_t QuestQuery::GetSeriesQuestChildList(const IVarList& args, IVarList& result)
{
    int quest_id = args.IntVal(0);

    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        std::string children = series_quest_wrap.GetChild();

        char buffer[32];
        const char* result_ids[10];
        size_t amount = StringUtil::SplitString(children.c_str(), ',', buffer,sizeof(buffer), result_ids, 10);

        for (size_t i=0; i<amount; ++i)
        {
            int child_id = ::atoi(result_ids[i]);

            if (child_id > 0)
            {
                result.AddInt(child_id);
            }

        }

    }

    return result.GetCount();
}


const char* QuestQuery::GetSeriesQuestChildStr(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        std::string children = series_quest_wrap.GetChild();

        return children.c_str();

    }

    return "";
}


bool QuestQuery::GetSeriesQuestHide(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        bool is_hide = series_quest_wrap.GetHide();

        return is_hide;
    }

    return false;
}


bool QuestQuery::GetSeriesQuestLast(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        bool is_last = series_quest_wrap.GetLast();

        return is_last;
    }

    return false;
}


//bool QuestQuery::GetSeriesQuestLast(int quest_id)
//{
//    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);
//
//    if (series_quest_wrap.IsValid())
//    {
//        bool is_last = series_quest_wrap.GetLast();
//
//        return is_last;
//    }
//
//    return false;
//}


size_t QuestQuery::GetSeriesQuestGridPoints(const IVarList& args, IVarList& result)
{
    int quest_id = args.IntVal(0);

    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        int pos_x = series_quest_wrap.GetGridX();
        int pos_y = series_quest_wrap.GetGridY();

        result.AddInt(pos_x);
        result.AddInt(pos_y);
    }

    return result.GetCount();

}


const char* QuestQuery::GetSeriesTitleDes(const char* series_id)
{
    SeriesWrap series_wrap = SeriesWrap(series_id);

    if (series_wrap.IsValid())
    {
        std::string title = series_wrap.GetTitle();
        return title.c_str();
    }

    return "";
}


int QuestQuery::GetSeriesSortProp(const char* series_id)
{
    SeriesWrap series_wrap = SeriesWrap(series_id);

    if (series_wrap.IsValid())
    {
        int sort_num = series_wrap.GetSortNum();
        return sort_num;
    }

    return -1;
}


int QuestQuery::GetSeriesEffectQuest(const char* series_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return -1;
    }

    //std::map<int, std::string> mapSeries;

    if (pClientPlayer->FindRecord(quest_series_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_series_rec << QUEST_SERIES_ID << series_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return -1;
        }

        int effect_quest_id = pClientPlayer->QueryRecordInt(quest_series_rec, row, QUEST_SERIES_QUEST_ID);

        return effect_quest_id;
    }

    return -1;
}

size_t QuestQuery::GetSeriesEffectQuestList(const IVarList& args, IVarList& result)
{
    const char* series_id = args.StringVal(0);
    if (NULL == series_id)
    {
        return result.GetCount();
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    //用于排序的临时容器
    std::list<int> series_quest_list;

    if (pClientPlayer->FindRecord(quest_series_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<<quest_series_rec<<QUEST_SERIES_ID<<series_id<<0, result_row);

        int series_row = result_row.IntVal(0);
        if (series_row < 0)
        {
            return result.GetCount();
        }

        int doing_quest = pClientPlayer->QueryRecordInt(quest_series_rec, series_row, QUEST_SERIES_QUEST_ID);
        if (doing_quest <= 0)
        {
            return result.GetCount();
        }

        int doing_quest_state = GetQuestState(doing_quest);

        if ( QUEST_STATUS_REWARDED == doing_quest_state)
        {
            CVarList result_child;
            size_t count = GetSeriesQuestChildList(CVarList()<<doing_quest,result_child);

            for (size_t i=0; i<count; ++i)
            {
                int child_quest = result_child.IntVal(i);

                series_quest_list.push_back(child_quest);
            }
        }

        series_quest_list.push_front(doing_quest);

        std::string parent = GetSeriesQuestParent(doing_quest);

        while(parent != "")
        {
            int parent_quest = ::atoi(parent.c_str());
            series_quest_list.push_front(parent_quest);

            parent = GetSeriesQuestParent(parent_quest);
        }

    }

    std::list<int>::iterator it = series_quest_list.begin();

    for (; it!=series_quest_list.end(); ++it)
    {
        result.AddInt(*it);
    }

    return result.GetCount();

}


size_t QuestQuery::GetSeriesFirstQuest(const IVarList& args, IVarList& result)
{
    const char* series_id = args.StringVal(0);

    SeriesWrap series_wrap = SeriesWrap(series_id);

    if (series_wrap.IsValid())
    {
        series_wrap.GetFirstQuest(result);
    }

    return result.GetCount();
}


bool QuestQuery::IsSeriesFirstQuest(const char* series_id, int quest_id)
{
    if (NULL == series_id)
    {
        return false;
    }

    SeriesWrap series_wrap = SeriesWrap(series_id);

    size_t quest_count = 0;
    CVarList result;

    if (series_wrap.IsValid())
    {
        quest_count = series_wrap.GetFirstQuest(result);
    }

    if (quest_count == 0)
    {
        return false;
    }

    for (size_t i=0; i<quest_count; ++i)
    {
        int first_quest_id = result.IntVal(i);

        if (first_quest_id == quest_id)
        {
            return true;
        }
    }


    return false;
}


bool QuestQuery::IsSeriesLastQuest(int quest_id)
{
    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        bool is_last = series_quest_wrap.GetLast();

        return is_last;

    }

    return false;
}

size_t QuestQuery::GetSeriesLastQuest(const IVarList& args, IVarList& result)
{
    const char* series_id = args.StringVal(0);

    SeriesWrap series_wrap = SeriesWrap(series_id);

    if (series_wrap.IsValid())
    {
        series_wrap.GetLastQuest(result);
    }

    return result.GetCount();
}


int QuestQuery::GetSeriesQuestByPos(const char* series_id, int x, int y)
{
    SeriesWrap series_wrap = SeriesWrap(series_id);
    if (series_wrap.IsValid())
    {
        CVarList result;
        size_t count = series_wrap.GetSeriesQuestList(series_id, result);

        for (size_t i=0; i<count; ++i)
        {
            int quest_id = result.IntVal(i);

            int pos_x = -1;
            int pos_y = -1;

            CVarList result_pos;
            size_t count_pos = GetSeriesQuestGridPoints(CVarList()<<quest_id, result_pos);
            if (count_pos == 2)
            {
                pos_x = result_pos.IntVal(0);
                pos_y = result_pos.IntVal(1);
            }

            if (pos_x < 0 || pos_y < 0)
            {
                continue;
            }

            if (pos_x != x || pos_y != y)
            {
                continue;
            }

            //父任务展开,当前任务才能刷新在坐标控件上
            std::string parent_quest_id = GetSeriesQuestParent(quest_id);

            if ( strcmp(parent_quest_id.c_str(), "") == 0 ||
                GetSeriesQuestOpend( ::atoi(parent_quest_id.c_str()) ))
            {
                return quest_id;
            }

        }

    }

    return -1;
}


bool QuestQuery::GetSeriesAbility(const char* series_id)
{
    if (NULL == series_id)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    if (pClientPlayer->FindRecord(quest_series_rec))
    {
        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_series_rec << QUEST_SERIES_ID << series_id << 0, result_row);

        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return false;
        }

        int state = pClientPlayer->QueryRecordInt(quest_series_rec, row, QUEST_SERIES_STATUS);

        if (state == QUEST_SERIES_STATUS_DOING)
        {
            return true;
        }   
    }

    return false;
}


size_t QuestQuery::GetEffectSeriesList(const IVarList& args, IVarList& result)
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    std::map<int, std::string> mapSeries;

    if (pClientPlayer->FindRecord(quest_series_rec))
    {
        size_t row = pClientPlayer->GetRecordRows(quest_series_rec);

        for(size_t i=0; i<row; ++i)
        {
            std::string series_id = pClientPlayer->QueryRecordString(quest_series_rec, i, QUEST_SERIES_ID);

            int state = pClientPlayer->QueryRecordInt(quest_series_rec, i, QUEST_SERIES_STATUS);

            /*int valid_quest = pClientPlayer->QueryRecordInt(quest_series_rec, i, QUEST_SERIES_QUEST_ID);

            if (valid_quest == 0)
            {
            continue;
            }*/

            if (state == QUEST_SERIES_STATUS_DOING)
            {
                int series_sort = GetSeriesSortProp(series_id.c_str());

                std::map<int, std::string>::iterator iter = mapSeries.find(series_sort);
                if (iter == mapSeries.end())
                {
                    mapSeries.insert(std::map<int, std::string>::value_type(series_sort, series_id));
                }
            }
        }


        std::map<int, std::string>::iterator iter = mapSeries.begin();


        for (; iter != mapSeries.end(); ++iter)
        {
            std::string series_id = iter->second;

            result.AddString(series_id.c_str());
        }


    }

    return result.GetCount();
}


size_t QuestQuery::GetSeriesQuestBrotherList(const IVarList& args, IVarList& result)
{
    int quest_id = args.IntVal(0);

    SeriesQuestWrap  series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        return series_quest_wrap.GetBrotherList(quest_id, result);
    }

    return result.GetCount();
}


bool QuestQuery::InitSeriesQuestOpend(const char* series_id)
{
    //系列头任务
    SeriesWrap series_wrap = SeriesWrap(series_id);

    if (series_wrap.IsValid())
    {
        CVarList result;
        size_t count = GetSeriesFirstQuest(CVarList()<<series_id, result);

        while(count > 0)
        {
            int opend_quest_id = -1;

            for (size_t i=0; i < count; ++i)
            {
                int quest_id = result.IntVal(i);

                int quest_state = GetQuestState(quest_id);

                if (quest_state == QUEST_STATUS_NONE)
                {
                    SetSeriesQuestOpend(quest_id, false);
                    continue;
                }

                opend_quest_id = quest_id;

                break;
            }

            result.Clear();
            count = result.GetCount();

            if (opend_quest_id > 0)
            {
                SetSeriesQuestOpend(opend_quest_id, true);

                count = GetSeriesQuestChildList(CVarList()<<opend_quest_id, result);
            }

        }

    }

    return true;
}


bool QuestQuery::GetSeriesQuestOpend(int quest_id)
{
    SeriesQuestWrap series_quest_wrap = SeriesQuestWrap(quest_id);

    if (series_quest_wrap.IsValid())
    {
        bool opend = series_quest_wrap.GetOpend();

        return opend;
    }

    return false;
}

bool QuestQuery::SetSeriesQuestOpend(int quest_id, bool opend)
{
    SeriesQuestWrap series_quest_wrap = SeriesQuestWrap(quest_id);
    if (series_quest_wrap.IsValid())
    {
        //如果任务为系列末任务,该任务始终收起
        bool is_last = GetSeriesQuestLast(quest_id);
        if (is_last)
        {
            series_quest_wrap.SetOpend(false);
            return true;
        }

        bool is_opend = series_quest_wrap.GetOpend();
        int quest_state = GetQuestState(quest_id);

        //设置任务展开
        if (opend)
        {
            if (is_opend)
            {
                return true;
            }

            bool quest_hide = GetQusetIsSpecialHide(quest_id);

            //任务未接取时不向后展开
            if (quest_state == QUEST_STATUS_NONE && quest_hide)
            {
                return true;
            }

            //设置所有兄弟任务及兄弟任务后续所有任务状态为关闭&设置自己展开
            CVarList result_brother;
            size_t brother_count = GetSeriesQuestBrotherList(CVarList()<<quest_id, result_brother);

            for (size_t i=0; i < brother_count; ++i)
            {
                int brother_quest_id = result_brother.IntVal(i);

                //如果兄弟任务中有已领取奖励的则默认兄弟任务展开自己关闭
                int brother_state = GetQuestState(brother_quest_id);

                if (brother_state == QUEST_STATUS_REWARDED)
                {
                    SetSeriesQuestOpend(brother_quest_id, true);
                    return true;
                }
                //兄弟任务中无已提交任务,则设置自己展开,兄弟任务收起
                else
                {
                    SetSeriesQuestOpend(brother_quest_id, false);
                }           
            }

            series_quest_wrap.SetOpend(true);
        }

        //设置收起
        else
        {
            if (!is_opend)
            {
                return true;
            }

            if (quest_state == QUEST_STATUS_REWARDED)
            {
                return true;
            }

            //将自己&其后所有被展开子任务关闭
            CVarList result_child;
            size_t child_count = GetSeriesQuestChildList(CVarList()<<quest_id, result_child);

            for (size_t i=0; i < child_count; ++i)
            {
                int child_quest_id = result_child.IntVal(i);
                SetSeriesQuestOpend(child_quest_id, false);
            }

            series_quest_wrap.SetOpend(false);
        }
    }

    return true;

}


size_t QuestQuery::GetAllBranchQuestIDList(const IVarList& args, IVarList& result)
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        size_t row = pClientPlayer->GetRecordRows(quest_rec);

        for(size_t i=0; i<row; ++i)
        {
            int quest_id = pClientPlayer->QueryRecordInt(quest_rec, i, QUEST_REC_ID);

            if (!IsSeriesQuest(quest_id))
            {
                result.AddInt(quest_id);
            }
        }
    }

    return result.GetCount();
}

size_t QuestQuery::GetBranchQuestIDList(const IVarList& args, IVarList& result)
{
    const char* scene = args.StringVal(0);

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    std::list<int> quest_id_list;
    quest_id_list.clear();

    if (pClientPlayer->FindRecord(quest_rec))
    {
        size_t row = pClientPlayer->GetRecordRows(quest_rec);

        for(size_t i=0; i<row; ++i)
        {
            int quest_id = pClientPlayer->QueryRecordInt(quest_rec, i, QUEST_REC_ID);
            std::string accept_scene = GetAcceptArea(quest_id);

            if (strcmp(scene, accept_scene.c_str()) == 0)
            {
                quest_id_list.push_back(quest_id);
            }
        }
    }

    std::list<int>::iterator it = quest_id_list.begin();
    for (;it!=quest_id_list.end(); ++it)
    {
        result.AddInt(*it);
    }

    return result.GetCount();
}

size_t QuestQuery::GetBranchAreaList(const IVarList& args, IVarList& result)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return 0;
    }

    if (pClientPlayer->FindRecord(quest_rec))
    {
        std::set<std::string> setSceneID;

        size_t row_num = pClientPlayer->GetRecordRows(quest_rec);

        for(size_t i=0; i<row_num; ++i)
        {
            int quest_id = pClientPlayer->QueryRecordInt(quest_rec, i, QUEST_REC_ID);

            std::string scene_id = GetAcceptArea(quest_id);
            //防止场景ID为空 by add lizy
            if (!scene_id.empty())
            {
                setSceneID.insert(scene_id);
            }                
        }

        std::set<std::string>::iterator iter = setSceneID.begin();
        for (; iter!=setSceneID.end(); ++iter)
        {
            result.AddString((*iter).c_str());
        }
    }

    return result.GetCount();

}

size_t QuestQuery::GetRecommendAreaList(const IVarList& args, IVarList& result)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return 0;
    }

    int player_level = pClientPlayer->QueryPropInt("Level");

    CVarList ivar;
    size_t count = QuestBaseData::instance().GetPlayerCurRecQuest(player_level,ivar);

    std::set<std::string> setSceneID;

    for (size_t i = 0; i < count; i++)
    {
        int quest_id = ivar.IntVal(i);

        std::string scene_id = GetAcceptArea(quest_id);
        if (CanAcceptQuest(quest_id))
        {
            //防止场景ID为空 by add lizy
            if (!scene_id.empty())
            {
                setSceneID.insert(scene_id);
            }
        }
    }

    std::set<std::string>::iterator iter = setSceneID.begin();
    for (; iter!=setSceneID.end(); ++iter)
    {
        result.AddString((*iter).c_str());
    }


    return result.GetCount();
}

size_t QuestQuery::GetRecommendQuestIDList(const IVarList& args, IVarList& result)
{
    const char* scene = args.StringVal(0);

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    int player_level = pClientPlayer->QueryPropInt("Level");

    CVarList ivar;
    size_t count = QuestBaseData::instance().GetPlayerCurRecQuest(player_level,ivar);

    std::list<int> quest_id_list;
    quest_id_list.clear();

    for (size_t i = 0; i < count; i++)
    {
        int quest_id = ivar.IntVal(i);
        std::string accept_scene = GetAcceptArea(quest_id);

        if (strcmp(scene, accept_scene.c_str()) == 0)
        {
            if (CanAcceptQuest(quest_id))
            {
                int quest_type = GetQuestType(quest_id);
                if (quest_type == QUEST_ACTIVE)
                {// 推荐任务中不包含隐藏任务
                    continue;
                }
                std::list<int>::iterator it = quest_id_list.begin();
                quest_id_list.push_back(quest_id);
            }
        }
    }

    std::list<int>::iterator it = quest_id_list.begin();
    for (;it!=quest_id_list.end(); ++it)
    {
        result.AddInt(*it);
    }

    return result.GetCount();
}

const char* QuestQuery::GetCriteriaTalkDialog(int criteria_id)
{
    QuestCriteriaWrap quest_criteria(criteria_id);
    if (!quest_criteria.IsValid())
    {
        return "";
    }

    if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
    {
        return "";
    }

    return (*quest_criteria.GetTalk().dialog_id).c_str();
}

int QuestQuery::GetCriteriaTalkRecoverItems(const IVarList& args, IVarList& result)
{
    result.Clear();

    int criteria_id = args.IntVal(0);

    QuestCriteriaWrap quest_criteria(criteria_id);
    if (!quest_criteria.IsValid())
    {
        return 0;
    }

    if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
    {
        return 0;
    }

    for (int i = 0; i < (int)quest_criteria.GetTalk().recover_items->size(); i++)
    {
        std::string item_name = (*quest_criteria.GetTalk().recover_items)[i].item_config;
        int count = (*quest_criteria.GetTalk().recover_items)[i].count;

        if (item_name.empty() || count == 0)
        {
            continue;
        }

        result.AddString(item_name.c_str());
        result.AddInt(count);
    }

    return (int)result.GetCount();
}

int QuestQuery::GetCriteriaTalkGiveItems(const IVarList& args, IVarList& result)
{
    result.Clear();

    int criteria_id = args.IntVal(0);

    QuestCriteriaWrap quest_criteria(criteria_id);
    if (!quest_criteria.IsValid())
    {
        return 0;
    }

    if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
    {
        return 0;
    }

    for (int i = 0; i < (int)quest_criteria.GetTalk().give_items->size(); i++)
    {
        std::string item_name = (*quest_criteria.GetTalk().give_items)[i].item_config;
        int count = (*quest_criteria.GetTalk().give_items)[i].count;

        if (item_name.empty() || count == 0)
        {
            continue;
        }

        result.AddString(item_name.c_str());
        result.AddInt(count);
    }

    return (int)result.GetCount();
}
int QuestQuery::GetCriteriaTalkCollectItems(const IVarList& args, IVarList& result)
{
    result.Clear();

    int criteria_id = args.IntVal(0);

    QuestCriteriaWrap quest_criteria(criteria_id);
    if (!quest_criteria.IsValid())
    {
        return 0;
    }

    if (QUEST_CRITERIA_TYPE_COLLECT_ITEM != quest_criteria.GetType())
    {
        return 0;
    }

    CriteriaDataCollectItem criteria_collect = quest_criteria.GetCollectItem();

    std::string item_name = *(criteria_collect.collect_item);
    int count = criteria_collect.collect_num;

    if (item_name.empty() || 0 == count)
    {
        return 0;
    }

    result.AddString(item_name.c_str());
    result.AddInt(count);

    return (int)result.GetCount();
}
const char* QuestQuery::GetNpcQuestFlagEffect(const char* npc_config)
{
    int flag = GetNpcQuestFlag(npc_config);

    std::map<int, NpcQuestFlagRes*>::iterator iter = m_npc_questflags_map.find(flag);
    if (iter == m_npc_questflags_map.end())
    {
        return "";
    }

    return iter->second->effect_flag.c_str();
}

const char* QuestQuery::GetNpcQuestFlagImage(const char* npc_config)
{
    int flag = GetNpcQuestFlag(npc_config);

    std::map<int, NpcQuestFlagRes*>::iterator iter = m_npc_questflags_map.find(flag);
    if (iter == m_npc_questflags_map.end())
    {
        return "";
    }

    return iter->second->image_flag.c_str();
}

bool QuestQuery::IsNpcHaveQuest(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.find(npc_config);
    if (iter == m_npc_quests_map.end())
    {
        return false;
    }
    return true;
}

int QuestQuery::GetNpcQuestFlag(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return -1;
    }

    CVarList args, res_accept, res_submit;

    args << npc_config;

    const int submit_len = GetSubmitQuestMenus(args, res_submit);
    const int accept_len = GetAcceptQuestMenus(args, res_accept);

    if (submit_len)
    {
        bool blue_flag = false;

        for (int i = 0; i < submit_len; i++)
        {
            int quest_id = res_submit.IntVal(i);
            QuestWrap quest(quest_id);
            if (!quest.IsValid())
            {
                continue;
            }

            if (quest.IsTimeRepeat())
            {
                blue_flag = true;
                break;
            }
        }

        if (blue_flag)
        {
            return NPC_QUEST_EFFECT_SUBMIT_BLUE;
        }
        else
        {
            return NPC_QUEST_EFFECT_SUBMIT_YELLOW;
        }
    }
    else if (IsNpcSatisfyInter(npc_config))
    {
        return NPC_QUEST_EFFECT_INTER;
    }
    else if (IsNpcSatisfyGather(npc_config))
    {
        return NPC_QUEST_EFFECT_GATHER;
    }
    else if (IsNpcSatisfyUseItem(npc_config))
    {
        return NPC_QUEST_EFFECT_USEITEM;
    }
    else if (accept_len)
    {
        bool blue_flag = false;
        bool yellow_flag = false;
        bool red_flag = false;

        for (int i = 0; i < accept_len; i++)
        {
            int quest_id = res_accept.IntVal(i);
            QuestWrap quest(quest_id);
            if (!quest.IsValid())
            {
                continue;
            }

            if (!CanAcceptQuest(quest_id))
            {
                continue;
            }            

            if (quest.IsTimeRepeat())
            {
                blue_flag = true;
                break;
            }

            if (GetLevel() - quest.GetMinLevel() <= 3)
            {
                yellow_flag = true;
                break;
            }

            if (quest.GetQuestLevel() - GetLevel() >= 3)
            {
                red_flag = true;
                break;
            }
        }
        if (blue_flag)
        {
            return NPC_QUEST_EFFECT_ACCEPT_BULE;
        }
        else if (yellow_flag)
        {
            return  NPC_QUEST_EFFECT_ACCEPT_YELLOW;
        }
        else if (red_flag)
        {
            return NPC_QUEST_EFFECT_ACCEPT_RED;
        }
        else
        {
            return NPC_QUEST_EFFECT_ACCEPT_GREEN;
        }
    }
    else if (IsNpcSatisfyUnComplete(npc_config))
    {
        return NPC_QUEST_EFFECT_SUBMIT_GREY;
    }

    return -1;
}

bool QuestQuery::HideNpcQuestEffect(const PERSISTID& client_scene_obj)
{
    IGameObject* pGameObject = (IGameObject*)GetCore()->GetEntity(client_scene_obj);

    if (NULL == pGameObject)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }

    GameVisual * pGameVisual = (GameVisual *)CHelper::GetGlobalEntity("game_visual");

    if (NULL == pGameVisual)
    {
        return false;
    }

    PERSISTID vis_object;
    ClientToVisual(client_scene_obj, vis_object);

    IVisBase* pVis = (IVisBase*)GetCore()->GetEntity(vis_object);
    if (NULL == pVis)
    {
        return false;
    }

    if (!pVis->GetLoadFinish())
    {
        return false;
    }

    RoleComposite * pRoleComposite =
        (RoleComposite *)CHelper::GetGlobalEntity("role_composite");

    IVisBase * pActor2 = ((IVisBase *)CHelper::GetEntity(vis_object));

    if (NULL == pRoleComposite)
    {
        return false;
    }

    if (NULL == pActor2)
    {
        return false;
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    const char* npc_config = pGameObject->QueryPropString("ConfigID");
    std::string script = pNpcQuery->GetNpcProp(npc_config, "script");


    if (strcmp(script.c_str(), "GivingNpc") == 0)
    {
        pRoleComposite->LinkEffect(vis_object, "npc_quest_effect", "");
    }
    else
    {

    }

    return true;
}
bool QuestQuery::RefreshNpcQuestEffect(const PERSISTID& client_scene_obj)
{
    IGameObject* pGameObject = (IGameObject*)GetCore()->GetEntity(client_scene_obj);

    if (NULL == pGameObject)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }

    GameVisual * pGameVisual = (GameVisual *)CHelper::GetGlobalEntity("game_visual");

    if (NULL == pGameVisual)
    {
        return false;
    }

    PERSISTID vis_object;
    ClientToVisual(client_scene_obj, vis_object);

    IVisBase* pVis = (IVisBase*)GetCore()->GetEntity(vis_object);
    if (NULL == pVis)
    {
        return false;
    }

    RoleComposite * pRoleComposite =
        (RoleComposite *)CHelper::GetGlobalEntity("role_composite");

    IVisBase * pActor2 = ((IVisBase *)CHelper::GetEntity(vis_object));

    if (NULL == pRoleComposite)
    {
        return false;
    }

    if (NULL == pActor2)
    {
        return false;
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    std::string npc_config = pGameObject->QueryPropString("ConfigID");
    if (npc_config.empty())
    {
        return false;
    }

    std::string script = pNpcQuery->GetNpcProp(npc_config.c_str(), "script");
    if (strcmp(script.c_str(), "GivingNpc") == 0)
    {
        pRoleComposite->LinkEffect(vis_object, "npc_quest_effect", "");
    }


    if (!pGameObject->FindProp("Type"))
    {
        return false;
    }

    int obj_type = pGameObject->QueryPropInt("Type");
    if (obj_type != TYPE_NPC)
    {
        return false;
    }

    if (!pGameObject->FindProp("ConfigID"))
    {
        return false;
    }

    if (CHelper::QueryCustomBool(pActor2, "ServerDead"))
    {
        return false;
    }

    if (pGameObject->FindProp("LogicState"))
    {
        if (pGameObject->QueryPropInt("LogicState") == LS_FIGHTING)
        {
            return false;
        }
    }

    const char* effect_name = GetNpcQuestFlagEffect(npc_config.c_str());
    if (NULL == effect_name || strcmp(effect_name, "") == 0)
    {
        return false;
    }

    if (strcmp(script.c_str(), "GivingNpc") == 0)
    {
        pRoleComposite->LinkEffect(vis_object, "npc_quest_effect", effect_name);
    }

    return true;
}

void QuestQuery::ClientToVisual(const PERSISTID& client_obj, PERSISTID& visual_obj) const
{
    GameVisual* pGameVisual = (GameVisual*)CHelper::GetGlobalEntity("game_visual");
    if( pGameVisual )
    {
        IEntity* pClient = GetCore()->GetEntity(client_obj);

        if (pClient)
        {
            fast_string strIdent = CHelper::QueryPropertyString(pClient, "Ident");

            visual_obj = pGameVisual->GetSceneObj(strIdent.c_str());
        }
    }
}

bool QuestQuery::IsNpcSatisfyInter(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    std::string script = pNpcQuery->GetNpcProp(npc_config, "script");

    if (script != "CommonNpc")
    {
        return false;
    }

    int rows = pClientPlayer->GetRecordRows(quest_criteria_rec);
    for (int i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_CRITERIA_ID);

        int status = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_STATUS);

        int parent_type = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_PARENT_TYPE);

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
        {
            continue;
        }

        if (status != QUEST_CRITERIA_STATUS_DOING)
        {
            continue;
        }

        if (parent_type != CRITERIA_PARENT_QUEST)
        {
            continue;
        }
        if (!IsStepQuestCriteria(criteria_id))
        {            
            continue;                    
        }
        std::string inter_npc = *(quest_criteria.GetTalk().npc_id);
        if (inter_npc == npc_config)
        {
            return true;
        }
    }

    return false;
}

size_t QuestQuery::GetNpcSatisfyInterQuestMenus(const IVarList& args, IVarList& result)
{
    const char* npc_config = args.StringVal(0);

    if (NULL == npc_config)
    {
        return result.GetCount();
    }

    if (strcmp(npc_config, "") == 0)
    {
        return result.GetCount();
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return result.GetCount();
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    std::string script = pNpcQuery->GetNpcProp(npc_config, "script");

    if (script != "CommonNpc")
    {
        return result.GetCount();
    }

    std::set<int> sSatisfyInterQuest;

    int rows = pClientPlayer->GetRecordRows(quest_criteria_rec);
    for (int i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_CRITERIA_ID);

        int status = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_STATUS);

        int parent_quest = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_PARENT_ID);

        int parent_type = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_PARENT_TYPE);


        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
        {
            continue;
        }

        if (status != QUEST_CRITERIA_STATUS_DOING)
        {
            continue;
        }

        std::string inter_npc = *(quest_criteria.GetTalk().npc_id);
        if (inter_npc != npc_config)
        {
            continue;
        }

        //子模板属于一个任务
        if (parent_type != 1)
        {
            continue;
        }

        sSatisfyInterQuest.insert(parent_quest);

    }

    std::set<int>::iterator iter = sSatisfyInterQuest.begin();

    for (; iter!=sSatisfyInterQuest.end(); ++iter)
    {
        result.AddInt(*iter);
    }

    return result.GetCount();

}

bool QuestQuery::IsNpcSatisfyGather(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    std::string script = pNpcQuery->GetNpcProp(npc_config, "script");

    if (script != "GivingNpc")
    {
        return false;
    }

    int rows = pClientPlayer->GetRecordRows(quest_criteria_rec);
    for (int i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_CRITERIA_ID);

        int status = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_STATUS);

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_COLLECT_ITEM)
        {
            continue;
        }

        if (status != QUEST_CRITERIA_STATUS_DOING)
        {
            continue;
        }    
        if (IsStepQuestCriteria(criteria_id))
        {            
            continue;                    
        }
        const CriteriaDataCollectItem& collect_item = quest_criteria.GetCollectItem();
        const int len = static_cast<int>(collect_item.flop_npc_list->size());

        for (int i = 0; i < len; i++)
        {
            if ((*collect_item.flop_npc_list)[i] == npc_config)
            {
                return true;
            }
        }
    }

    return false;
}

bool QuestQuery::IsNpcSatisfyUseItem(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }

    NpcPropQuery *pNpcQuery =(NpcPropQuery*)CHelper::GetGlobalEntity("npc_prop_query");
    if (pNpcQuery == NULL)
    {
        return false;
    }

    std::string script = pNpcQuery->GetNpcProp(npc_config, "script");

    if (script != "CommonNpc")
    {
        return false;
    }

    int rows = pClientPlayer->GetRecordRows(quest_criteria_rec);
    for (int i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_CRITERIA_ID);

        int status = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_STATUS);

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        if (quest_criteria.GetType() != QUEST_CRITERIA_TYPE_USEITEM_LOCKTARGET)
        {
            continue;
        }

        if (status != QUEST_CRITERIA_STATUS_DOING)
        {
            continue;
        }
        if (IsStepQuestCriteria(criteria_id))
        {            
            continue;                    
        }
        std::string target_npc = *(quest_criteria.GetUseItemLock().target_npc);
        if (target_npc == npc_config)
        {
            return true;
        }
    }

    return false;
}

bool QuestQuery::IsNpcSatisfyAccept(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    CVarList args, res;
    args << npc_config;
    return GetAcceptQuestMenus(args, res) > 0 ? true : false;
}

bool QuestQuery::IsNpcSatisfySubmit(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    CVarList args, res;
    args << npc_config;
    return GetSubmitQuestMenus(args, res) > 0 ? true : false;
}

bool QuestQuery::IsNpcSatisfyUnComplete(const char* npc_config)
{
    if (NULL == npc_config)
    {
        return false;
    }

    if (strcmp(npc_config, "") == 0)
    {
        return false;
    }

    std::map<std::string, NpcQuests*>::iterator iter
        = m_npc_quests_map.find(npc_config);

    if (iter == m_npc_quests_map.end())
    {
        return false;
    }    
    for (int i = 0; i < (int)iter->second->canSubmitQuests.size(); i++)
    {
        int quest_id = iter->second->canSubmitQuests[i];
        if (QUEST_CRITERIA_STEP_CAN == IsCanStepQuestCriteria(npc_config, quest_id))
        {
            return true;
        }
    }
    return false;
}

bool QuestQuery::IsStepQuestCriteria(int criteria_id)
{

    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return false;
    }
    if (pClientPlayer->FindRecord(quest_criteria_rec))
    {
        CVarList row;
        pClientPlayer->FindRecordRow(CVarList() << quest_criteria_rec
            << QUEST_CRITERIA_REC_CRITERIA_ID << criteria_id << 0, row);

        int parent_id = pClientPlayer->QueryRecordInt(quest_criteria_rec, row.IntVal(0), QUEST_CRITERIA_REC_PARENT_ID);

        if (GetQuestIsStep(parent_id))
        {
            if (GetQuestStep(parent_id) == criteria_id)
            {
                return true;
            }
        }            
    }
    return false;
}

bool QuestQuery::CanAcceptQuest(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    if (IsQuestDoing(quest_id))
    {
        return false;
    }

    if (IsCriteriaDoing(quest_id))
    {
        return false;
    }

    if (quest.IsTimeRepeat())
    {
        if (IsRepeatQuestMaxNum(quest_id))
        {
            return false;
        }
    }
    else
    {
        if (IsQuestReward(quest_id))
        {
            return false;
        }    
    }

    if (!IsSatisfyMinLevel(quest_id))
    {
        return false;
    }

    if (!IsPreQuestReward(quest_id))
    {
        return false;
    }

    if (IsHaveParallelQuest(quest_id))
    {
        return false;
    }

    if (!IsSatisfyQuestCondition(quest_id))
    {
        return false;
    }
    //判断是否符合职业类型
    if (!IsSatisfyRoleIndex(quest_id))
    {
        return false;
    }

    return true;
}

bool QuestQuery::IsQuestDoing(int quest_id)
{
    int status = GetQuestState(quest_id);
    return (status == QUEST_STATUS_DOING) ||
        (status == QUEST_STATUS_CANSUBMIT) ||
        (status ==QUEST_STATUS_FAILED);
}

bool QuestQuery::IsCriteriaDoing(int quest_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    QuestWrap quest(quest_id);
    for (int i = 0; i < (int)quest.GetCriteriaList().size(); i++)
    {
        int criteria_id = quest.GetCriteriaList()[i];

        CVarList result_row;
        pClientPlayer->FindRecordRow(CVarList()<< quest_criteria_rec << QUEST_CRITERIA_REC_CRITERIA_ID << criteria_id << 0, result_row);
        int row = result_row.IntVal(0);

        if (row < 0)
        {
            return false;
        }
    }

    return true;
}

bool QuestQuery::IsQuestReward(int quest_id)
{
    return GetQuestState(quest_id) == QUEST_STATUS_REWARDED;
}

bool QuestQuery::IsSatisfyMinLevel(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    int level = pClientPlayer->QueryPropInt("Level");

    return quest.GetMinLevel() <= level ? true : false;
}
//判断是否符合职业类型
bool QuestQuery::IsSatisfyRoleIndex(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }
    int nRoleIndex = pClientPlayer->QueryPropInt("RoleIndex");
    if (0 == quest.GetRoleIndex())
    {
        //不区分职业
        return true;
    }
    return quest.GetRoleIndex() == nRoleIndex ? true : false;
}
bool QuestQuery::IsRepeatQuestMaxNum(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsTimeRepeat())
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    CVarList res,args;

    args << repeat_quest_rec << REPEAT_REC_QUEST_ID << quest_id << 0;

    pClientPlayer->FindRecordRow(args, res);

    int row = res.IntVal(0);

    if (row < 0)
    {
        return false;
    }

    int cur_num = pClientPlayer->QueryRecordInt(repeat_quest_rec,
        row, REPEAT_REC_QUEST_CURNUM);

    int max_num = pClientPlayer->QueryRecordInt(repeat_quest_rec,
        row, REPEAT_REC_QUEST_MAXNUM);

    if (cur_num >= max_num)
    {
        return true;
    }

    return false;
}

bool QuestQuery::IsPreQuestReward(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    if (quest.GetPreQuestList().empty())
    {
        return true;
    }

    for (int i = 0; i < (int)quest.GetPreQuestList().size(); i++)
    {
        if (GetQuestState(quest.GetPreQuestList()[i]) == QUEST_STATUS_REWARDED)
        {
            return true;
        }
    }

    return false;
}

bool QuestQuery::IsHaveParallelQuest(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    for (int i = 0; i < (int)quest.GetParQuestList().size(); i++)
    {
        if (GetQuestState(quest.GetParQuestList()[i]) != QUEST_STATUS_NONE)
        {
            return true;
        }
    }

    return false;
}

bool QuestQuery::IsHaveConvoyCriteria()
{
    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    int rows = pClientPlayer->GetRecordRows(quest_criteria_rec);
    for (int i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_CRITERIA_ID);
        int status = pClientPlayer->QueryRecordInt(quest_criteria_rec,
            i, QUEST_CRITERIA_REC_STATUS);

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        int type = quest_criteria.GetType();

        if (type == QUEST_CRITERIA_TYPE_CONVOY && status == QUEST_CRITERIA_STATUS_DOING)
        {
            return true;
        }
    }

    return false;
}

bool QuestQuery::IsSatisfyQuestCondition(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    ConditionManager * pConditionManager =
        (ConditionManager *)CHelper::GetGlobalEntity("ConditionManager");

    if (NULL == pConditionManager)
    {
        return false;
    }


    for (int i = 0; i < (int)quest.GetAcceptLimitList().size(); ++i)
    {
        int id = quest.GetAcceptLimitList()[i];
        if (id <= 0)
        {
            continue;
        }

        if (!pConditionManager->CanSatisfyCondition(pClientPlayer->GetID(),
            pClientPlayer->GetID(), id))
        {
            return false;
        }
    }

    return true;
}

bool QuestQuery::CanSubmitQuest(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    int status = GetQuestState(quest_id);

    if (status == QUEST_STATUS_NONE)
    {
        return false;
    }

    if (GetQuestState(quest_id) != QUEST_STATUS_CANSUBMIT)
    {
        return false;
    }

    return true;
}

int QuestQuery::GetDoingQuestMenus(const IVarList& args, IVarList& result)
{
    const char* npc_config = args.StringVal(0);

    if (NULL == npc_config)
    {
        return 0;
    }

    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.find(npc_config);

    if (iter == m_npc_quests_map.end())
    {
        return 0;
    }

    for (int i = 0; i < (int)iter->second->canAcceptQuests.size(); i++)
    {
        int quest_id = iter->second->canAcceptQuests[i];
        if (QUEST_CRITERIA_STEP_FAILED != IsCanStepQuestCriteria(npc_config, quest_id))
        {
            int quest_state = GetQuestState(quest_id);        
            if (QUEST_STATUS_DOING == quest_state)
            {
                result.AddInt(quest_id);
            }
        }
    }

    return (int)result.GetCount();
}

int QuestQuery::GetAcceptQuestMenus(const IVarList& args, IVarList& result)
{
    const char* npc_config = args.StringVal(0);

    if (NULL == npc_config)
    {
        return 0;
    }

    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.find(npc_config);

    if (iter == m_npc_quests_map.end())
    {
        return 0;
    }

    IGameClient *pGameClient = (IGameClient *)CHelper::GetGlobalEntity("game_client");
    if (!pGameClient)
    {
        return 0;
    }

    PERSISTID sceneID = pGameClient->GetScene();
    int protoID = CHelper::QueryPropertyInt(CHelper::GetEntity(sceneID), "ProtoSceneID");

    for (int i = 0; i < (int)iter->second->canAcceptQuests.size(); i++)
    {
        int quest_id = iter->second->canAcceptQuests[i];

        QuestWrap quest(quest_id);
        if (!quest.IsValid())
        {
            continue;
        }

        if (atoi(quest.GetAcceptArea()) != protoID)
        {
            continue;
        }

        if (QUEST_CRITERIA_STEP_FAILED != IsCanStepQuestCriteria(npc_config, quest_id))
        {
            if (CanAcceptQuest(quest_id))
            {
                result.AddInt(quest_id);
            }
        }
    }

    return (int)result.GetCount();
}

int QuestQuery::GetSubmitQuestMenus(const IVarList& args, IVarList& result)
{
    const char* npc_config = args.StringVal(0);

    if (NULL == npc_config)
    {
        return 0;
    }

    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.find(npc_config);

    if (iter == m_npc_quests_map.end())
    {
        return 0;
    }

    for (int i = 0; i < (int)iter->second->canSubmitQuests.size(); i++)
    {
        int quest_id = iter->second->canSubmitQuests[i];
        if (QUEST_CRITERIA_STEP_FAILED != IsCanStepQuestCriteria(npc_config, quest_id))
        {
            if (CanSubmitQuest(quest_id))
            {
                result.AddInt(quest_id);
            }
        }        
    }

    return (int)result.GetCount();
}
int QuestQuery::IsCanStepQuestCriteria(const char* npc_config, int quest_id)
{
    IGameObject* pClientPlayer = GetMainPlayer();

    if (NULL == pClientPlayer)
    {
        return QUEST_CRITERIA_STEP_FAILED;
    }    

    CVarList result_row;
    pClientPlayer->FindRecordRow(CVarList()<< quest_rec << QUEST_REC_ID << quest_id << 0, result_row);

    int row = result_row.IntVal(0);

    if (row < 0)
    {
        return QUEST_CRITERIA_STEP_NONE;
    }

    //获得任务的子任务判断
    QuestWrap quest(quest_id);

    if (!quest.IsValid())
    {
        return QUEST_CRITERIA_STEP_FAILED;
    }
    int bIsCan = QUEST_CRITERIA_STEP_NONE;
    for (int i = 0; i < (int)quest.GetCriteriaList().size(); i++)
    {
        int criteria_id = quest.GetCriteriaList()[i];

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }        
        if (GetQuestIsStep(quest_id))
        {
            if (GetQuestStep(quest_id) != criteria_id)
            {
                continue;
            }
        }    
        if (QUEST_CRITERIA_TYPE_TALK == quest_criteria.GetType())
        {
            std::string inter_npc = *(quest_criteria.GetTalk().npc_id);
            if (inter_npc != npc_config)
            {
                continue;
            }
        }        
        bIsCan = QUEST_CRITERIA_STEP_CAN;
    }
    return bIsCan;
}

//杨源 为任务超链接提供接口
//返回的表数据中包括SceneID、NpcList、ItemID、AreaPoints数据项,根据模板类型不同提取不同数据处理,任务可提交时仅返回提交npc
size_t QuestQuery::GetCriteriaHyperlinkInfobyhyper(const IVarList& args, IVarList& result)
{
    int criteria = args.IntVal(0);

    int criteria_type = GetCriteriaType(criteria);

    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);
    if (!quest_criteria_wrap.IsValid())
    {
        return result.GetCount();
    }

    //区域名称
    std::string area_name = "";


    //记录场景信息
    int scene_id = -1;

    //击杀类
    if (criteria_type == QUEST_CRITERIA_TYPE_KILL_NPC)
    {
        CriteriaDataKillNPC criteria_kill = quest_criteria_wrap.GetKillNpc();

        StrList* npc_list = criteria_kill.kill_npc_list;

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        StrList::iterator it_vec = (*npc_list).begin();
        for (; it_vec!=(*npc_list).end(); ++it_vec)
        {
            std::string npc = *it_vec;

            if (key[0] == 0)
            {
                SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str() );
            }
            else
            {
                SafeSprintf(key, sizeof(key), "%s,%s", key, npc.c_str() );  
            }

        }

        result.AddString(key);
    }
    //对话类
    else if (criteria_type == QUEST_CRITERIA_TYPE_TALK)
    {
        CriteriaDataTalk criteria_talk = quest_criteria_wrap.GetTalk();

        std::string npc = *(criteria_talk.npc_id);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str() );

        result.AddString(key);

    }


    //锁定目标(npc)使用物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_LOCKTARGET)
    {
        CriteriaDataUseItemLock criteria_lockuse = quest_criteria_wrap.GetUseItemLock();

        std::string target = *(criteria_lockuse.target_npc);
        std::string use_item = *(criteria_lockuse.use_item);

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "NpcList=%s", target.c_str() );

        result.AddString(key);
        memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "ItemID=%s", use_item.c_str() );

        result.AddString(key);

    }


    //区域使用物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_USEITEM_AREA)
    {
        CriteriaDataUseItemArea criteria_usearea = quest_criteria_wrap.GetUseItemArea();

        scene_id = criteria_usearea.scene_id;
        std::string use_item = *(criteria_usearea.use_item);
        float pos_x = criteria_usearea.x;
        float pos_y = criteria_usearea.y;
        float pos_z = criteria_usearea.z;

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "ItemID=%s", use_item.c_str() );

        result.AddString(key);
        memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "AreaPoints=%f,%f,%f", pos_x, pos_y, pos_z );

        result.AddString(key);

    }

    //搜集物品类
    else if (criteria_type == QUEST_CRITERIA_TYPE_COLLECT_ITEM)
    {
        CriteriaDataCollectItem criteria_collect = quest_criteria_wrap.GetCollectItem();

        StrList* npc_list = criteria_collect.flop_npc_list;

        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        StrList::iterator it_vec = (*npc_list).begin();
        for (; it_vec!=(*npc_list).end(); ++it_vec)
        {
            std::string npc = *it_vec;

            if (key[0] == 0)
            {
                SafeSprintf(key, sizeof(key), "NpcList=%s", npc.c_str() );
            }
            else
            {
                SafeSprintf(key, sizeof(key), "%s,%s", key, npc.c_str() );  
            }

        }

        result.AddString(key);
    }


    //区域信息
    area_name = GetCriteriaArea(criteria);
    if (area_name != "")
    {
        char key[128] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "AreaName=%s", area_name.c_str() );

        result.AddString(key);
    }

    if (scene_id > 0)
    {
        char key[32] = { 0 };
        //memset(key, 0, sizeof(key));

        SafeSprintf(key, sizeof(key), "SceneID=%d", scene_id);

        result.AddString(key);
    }

    return result.GetCount();
}

bool QuestQuery::CanPickQuestItem(const char* item_config)
{
    if (NULL == item_config)
    {
        return false;
    }

    IGameObject* pClientPlayer = GetMainPlayer();
    if (NULL == pClientPlayer)
    {
        return false;
    }

    size_t rows = pClientPlayer->GetRecordRows(quest_criteria_rec);

    for (size_t i = 0; i < rows; i++)
    {
        int criteria_id = pClientPlayer->QueryRecordInt(quest_criteria_rec, i, QUEST_CRITERIA_REC_CRITERIA_ID);

        QuestCriteriaWrap quest_criteria(criteria_id);
        if (!quest_criteria.IsValid())
        {
            continue;
        }

        int type = quest_criteria.GetType();
        // 只对收集物品类子模板有效
        if (type != QUEST_CRITERIA_TYPE_COLLECT_ITEM)
        {
            continue;
        }

        int curnum = pClientPlayer->QueryRecordInt(quest_criteria_rec, i, QUEST_CRITERIA_REC_CURNUM);
        int maxnum = pClientPlayer->QueryRecordInt(quest_criteria_rec, i, QUEST_CRITERIA_REC_MAXNUM);
        if (curnum == maxnum)
        {
            continue;
        }

        std::string item_name = *quest_criteria.GetCollectItem().collect_item;
        if (item_name == item_config)
        {
            return true;
        }
    }

    return false;
}

int QuestQuery::GetToAcceptQuestMenus(const IVarList &args, IVarList &result)
{
    const char* npc_config = args.StringVal(0);

    if (NULL == npc_config)
    {
        return 0;
    }

    std::map<std::string, NpcQuests*>::iterator iter = m_npc_quests_map.find(npc_config);

    if (iter == m_npc_quests_map.end())
    {
        return 0;
    }

    for (int i = 0; i < (int)iter->second->canAcceptQuests.size(); i++)
    {
        int quest_id = iter->second->canAcceptQuests[i];
        if (QUEST_CRITERIA_STEP_FAILED != IsCanStepQuestCriteria(npc_config, quest_id))
        {
            if (CanAcceptQuestIgnoreMinLevel(quest_id) && !IsSatisfyMinLevel(quest_id))
            {
                QuestWrap quest(quest_id);
                if (quest.IsValid())
                {
                    int min_level = quest.GetMinLevel();
                    int player_level = GetMainPlayerLevel();
                    if (min_level - player_level <= QUEST_TO_ACCEPT_LEVEL)
                    {
                        result.AddInt(quest_id);
                    }
                }
            }
        }
    }

    return (int)result.GetCount();
}

bool QuestQuery::CanAcceptQuestIgnoreMinLevel(int quest_id)
{
    QuestWrap quest(quest_id);
    if (!quest.IsValid())
    {
        return false;
    }

    if (IsQuestDoing(quest_id))
    {
        return false;
    }

    if (quest.IsTimeRepeat())
    {
        if (IsRepeatQuestMaxNum(quest_id))
        {
            return false;
        }
    }
    else
    {
        if (IsQuestReward(quest_id))
        {
            return false;
        }    
    }

    if (!IsPreQuestReward(quest_id))
    {
        return false;
    }

    if (IsHaveParallelQuest(quest_id))
    {
        return false;
    }

    if (!IsSatisfyQuestCondition(quest_id))
    {
        return false;
    }

    return true;
}

bool QuestQuery::IsCriteriaUsePortal(int criteria)
{
    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);
    if (!quest_criteria_wrap.IsValid())
    {
        return false;
    }

    PortalInfo & portalSequence = quest_criteria_wrap.GetPortalSequence();
    if (portalSequence.size() == 0)
    {
        return false;
    }

    return true;
}

size_t QuestQuery::GetCriteriaPortalInfo(const IVarList& args, IVarList& result)
{
    int criteria = args.IntVal(0);
    std::string areaIndex = args.StringVal(1);

    QuestCriteriaWrap quest_criteria_wrap = QuestCriteriaWrap(criteria);

    if (!quest_criteria_wrap.IsValid())
    {
        return result.GetCount();
    }

    PortalInfo & portalSequence = quest_criteria_wrap.GetPortalSequence();

    PortalInfo::iterator it = portalSequence.find(areaIndex);
    if (it != portalSequence.end())
    {
        for (size_t i = 0; i !=  (*it).second.size(); i++)
        {
            PortalPos pos = (*it).second[i];
            result << pos.x << pos.z;
        }
    }

    return result.GetCount() / 2;
}

// ================================
// 主线任务相关
// ================================
int QuestQuery::GetCurrentMainQuestID()
{
    IGameObject *player = GetMainPlayer();
    if (!player)
    {
        return -1;
    }

    if (!player->FindProp("CurrentMainQuestID"))
    {
        return -1;
    }

    int questID = player->QueryPropInt("CurrentMainQuestID");
    if (questID <= 0)
    {
        return -1;
    }

    return questID;
}

int QuestQuery::GetNextMainQuestID()
{
    IGameObject *player = GetMainPlayer();
    if (!player)
    {
        return -1;
    }

    if (!player->FindProp("CurrentMainQuestID"))
    {
        return -1;
    }

    int questID = player->QueryPropInt("CurrentMainQuestID");
    if (questID <= 0)
    {
        return -1;
    }

    QuestWrap quest(questID);
    if (!quest.IsValid())
    {
        return -1;
    }

    NumberList questList = quest.GetPostQuestList();
    if (questList.size() != 1)
    {
        return -1;
    }

    return questList[0];
}

int QuestQuery::GetRewardedMainQuestList(const IVarList& args, IVarList& result)
{
    IGameObject *player = GetMainPlayer();
    if (!player)
    {
        return -1;
    }

    if (!player->FindProp("CurrentMainQuestID"))
    {
        return -1;
    }

    int questID = player->QueryPropInt("CurrentMainQuestID");
    if (questID <= 0)
    {
        return -1;
    }

    if (GetQuestState(questID) == QUEST_STATUS_REWARDED)
    {
        result.AddInt(questID);
    }

    QuestWrap quest(questID);
    if (!quest.IsValid())
    {
        return -1;
    }

    NumberList prevQuestList = quest.GetPreQuestList();
    while (prevQuestList.size() == 1)
    {
        QuestWrap prevQuest(prevQuestList[0]);
        if (!prevQuest.IsValid())
        {
            return -1;
        }

        result.AddInt(prevQuest.GetID());

        prevQuestList = prevQuest.GetPreQuestList();
    }

    return result.GetCount();
}

bool QuestQuery::IsCriteriaVisibleInTrace(int criteria_id)
{
    if (criteria_id <= 0)
    {
        return false;
    }

    QuestCriteriaWrap criteria(criteria_id);
    if (!criteria.IsValid())
    {
        return false;
    }

    return criteria.IsVisible();
}

bool QuestQuery::IsCriteriaTalkWithFunc(int criteria_id)
{
    if (criteria_id <= 0)
    {
        return false;
    }

    QuestCriteriaWrap criteria(criteria_id);
    if (!criteria.IsValid())
    {
        return false;
    }

    if (criteria.GetType() != QUEST_CRITERIA_TYPE_TALK)
    {
        return false;
    }

    return criteria.GetTalk().is_func_talk;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值