-- 遗迹探宝 --
--开服第一天开启 单数天重置
--
local ObjHuman = require("core.ObjHuman")
local RoleLogic = require("role.RoleLogic")
local Util = require("common.Util")
local Msg = require("core.Msg")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local BagLogic = require("bag.BagLogic")
local CombatDefine = require("combat.CombatDefine")
local HeroGrid = require("hero.HeroGrid")
local YjTreasureExcel = require("excel.yjTreasure")
local YjTreasureDBLogic = require("yjTreasure.YjTreasureDB")
local Grid = require("bag.Grid")
local ItemDefine = require("bag.ItemDefine")
local CommonDB = require("common.CommonDB")
local YjTreasureCombat = require("yjTreasure.YjTreasureCombat")
local CombatLogic = require("combat.CombatLogic")
local LiLianLogic = require("dailyTask.LiLianLogic")
-- local MoshouLogic = require("moshou.MoshouLogic")
-- local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
-- local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local Timer = require("core.Timer")
local MengxinLogic = require("present.MengxinLogic")
local HeroGrowUp = require("absAct.HeroGrowUp")
local Log = require("common.Log")
local YunYingLogic = require("yunying.YunYingLogic")
local TriggerLogic = require("trigger.TriggerLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local TalismanLogic = require("talisman.TalismanLogic")

YJ_TREASURE_GRID_MAX = 25 --从左到右 从上到下 1-25个格子

YJ_TREASURE_GRID_KONGDI = 1 --空地
YJ_TREASURE_GRID_ITEM = 2 --道具
YJ_TREASURE_GRID_YJSHOPER = 3 --遗迹商人
YJ_TREASURE_GRID_TREASURE_SHOP = 4 --探险商店（格子内的商店）
YJ_TREASURE_GRID_BUFF = 5 --buff
YJ_TREASURE_GRID_SOUL = 6 --灵魂拷问
YJ_TREASURE_GRID_QUESTION = 7 --答题
YJ_TREASURE_GRID_DICE = 8 --骰子
YJ_TREASURE_GRID_BOX = 9 --宝箱
YJ_TREASURE_GRID_KEY = 10 --钥匙
YJ_TREASURE_GRID_MONSTER = 11 --怪物
YJ_TREASURE_GRID_BOSS = 12 --BOSS
YJ_TREASURE_GRID_DOOR = 13 --跳转口

YJ_YAOJI_CURE = 1 --生命药剂
YJ_YAOJI_KILL = 2 --死亡药剂

YJ_SHOP_YJSHOPER = 1 --神秘商人
YJ_SHOP_TREASURE_SHOP = 2 --遗迹商店

YJ_DICE_JINBI = 1 --好运骰子 金币
YJ_DICE_ZUANSHI = 2 --好运骰子 钻石

YJ_SHOP_ALLSHOP_SEND_MAX = 100 --探险商城商品列表展示上限

YJ_TREASURE_POS_MAX = 5 --上阵英雄上限

YJ_TREASURE_MONSTERS = 5 --怪物+boss

YJ_TREASURE_BILLBOARD_SHOW = 1000 --该名次外的玩家显示未上榜

YJ_TREASURE_QUICK_MAX = 10

--秘宝加成
function YJ_GetTalismanAdd(human)
	local dailyExtraSDTimes = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.YJ_DAILY_SD) or 0
	return dailyExtraSDTimes
end


-- 获取结束时间
local function YjTreasureLogic_GetEndTime()
    local nNowTime = os.time()
    local openDay = CommonDB.getServerOpenDay()
    if not openDay then
        openDay = 1
    end

    local tNowDate = os.date("*t", nNowTime)
    tNowDate.hour = 0
    tNowDate.min = 0
    tNowDate.sec = 0

    if openDay % 2 == 1 then
        tNowDate.day = tNowDate.day + 2
    else
        tNowDate.day = tNowDate.day + 1
    end

    local nEndTime = os.time(tNowDate)
    return nEndTime
end

function initAfterStart()
    local yjTime = CommonDB.getYjTreasureEndTime()
    if not yjTime then
        return
    end
    local now = os.time()
    if now >= (yjTime + 2 * 86400) then
        reset()
    end
end

function onZero()
    Timer.addLater(1, reset)
end

--重置
function reset()
    local openDay = CommonDB.getServerOpenDay()
    if not openDay then
        return
    end
    if openDay % 2 ~= 1 then
        return
    end

    beforeReset()

    local yjTime = CommonDB.getYjTreasureEndTime()
    if not yjTime then
        return
    end

    for uuid, roledata in pairs(YjTreasureDBLogic.YJ_Uuid2Role) do
        roledata.objList = nil
        roledata.layerData = nil
        roledata.tansuo = nil
        roledata.allShop = nil
        roledata.killMonster = nil
        roledata.buff = nil
        roledata.sangdang = nil
        roledata.time = nil
        roledata.yaojis = nil
        YjTreasureDBLogic.updateUuid2Role(roledata)
    end
    CommonDB.setYjTreasureEndTime(os.time())

    --刷新排行榜
    YjTreasureDBLogic.YJ_Rank2Uuid = {}
end

function beforeReset()
    for uuid, human in pairs(ObjHuman.onlineUuid) do
        -- 结束战斗
        CombatLogic.clientFinish(human, CombatDefine.COMBAT_TYPE10)
        human.db.combatQuick[CombatDefine.COMBAT_TYPE10] = 0

        -- 推送退出遗迹界面
        Msg.send(Msg.gc.GC_YJTREASURE_OUT, human.fd)
    end
end

--离重置剩余时间
function getLeftTime()
    local openDay = CommonDB.getServerOpenDay()
    if not openDay then
        return 0
    end

    local now = os.time()
    local nEndTime = YjTreasureLogic_GetEndTime()
    return nEndTime - now
    -- local nowStartTime = CommonDB.getYjTreasureEndTime()
    -- if openDay % 2 == 1 then --本轮活动第一天
    --     return nowStartTime + 86400 * 2 - now
    -- else --第二天
    --     return nowStartTime + 86400 - now
    -- end
end

function isOpen(human, sendErr)
    local openDay = CommonDB.getServerOpenDay()
    if not openDay then
        return Broadcast.sendErr(human, Lang.YJTREASURE_NOT_SET_OPEN_TIME)
    end

    --	if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_10011,sendErr) then
    --		return
    --	end

    if getLeftTime() < 1 then
        return
    end

    return true
end

local function makeHeroNet(net, obj, pos, human)
    local config = CombatLogic.getConfigByObj(obj)
    if obj.type == CombatDefine.COMBAT_OBJ_TYPE1 then
        HeroGrid.makeHeroSimple(net.heroSimple, obj, obj.bagIndex, human)
    else
        HeroGrid.makeHeroSimpleByMonsterID(net.heroSimple, obj.id, obj)
    end
    net.heroSimple.index = pos
    net.heroSimple.hpMax = YjTreasureDBLogic.getCombatObjHpMax(obj)
    net.heroSimple.hp = YjTreasureDBLogic.getCombatObjHp(obj)
    net.isFight = obj.isFight or 0
end

function makeYjGridDataNet(human, net, grid)
    net.type = grid.gridType

    local gridCnf = YjTreasureExcel.grid[grid.gridType]
    net.icon = gridCnf.icon

    net.item[0] = 0
    net.monster[0] = 0

    if grid.gridType == YJ_TREASURE_GRID_KONGDI then
        return
    end

    if grid.gridType == YJ_TREASURE_GRID_ITEM then
        net.item[0] = 1
        Grid.makeItem(net.item[1], grid.item.itemID, grid.item.itemCnt)
    end

    if grid.gridType == YJ_TREASURE_GRID_KEY then
        net.item[0] = 1
        Grid.makeItem(net.item[1], YjTreasureExcel.define[1].keyItemID, 1)
    end

    if grid.gridType == YJ_TREASURE_GRID_MONSTER or grid.gridType == YJ_TREASURE_GRID_BOSS then
        if grid.isOpen then
            net.monster[0] = 1
            for pos, obj in pairs(grid.monsterObjList) do
                if obj then
                    makeHeroNet(net.monster[1], obj, pos, human)
                end
            end
        end
    end
end

function makeYjGridNet(human, net, index, grid)
    net.index = index
    net.gridData[0] = 0
    if grid.isOpen or grid.gridType == YJ_TREASURE_GRID_BOSS then
        net.gridData[0] = 1
        makeYjGridDataNet(human, net.gridData[1], grid)
    end
end

local function dabiaoIsGet(uuid, dabiaoID)
    local killMonsterData = YjTreasureDBLogic.getKillMonsterData(uuid)
    if not killMonsterData or not killMonsterData.getList then
        return
    end

    return killMonsterData.getList[dabiaoID]
end

local function getNeedKillMonsterCnt(uuid)
    local conf = YjTreasureExcel.daBiaoReward
    local killMonsterData = YjTreasureDBLogic.getKillMonsterData(uuid)
    if not killMonsterData then
        return conf[#conf].needCnt
    end

    local nowCnt = killMonsterData and killMonsterData.killCnt or 0
    for i = 1, #conf do
        if not dabiaoIsGet(uuid, i) then
            return conf[i].needCnt
        end
    end

    return conf[#conf].needCnt
end

local function getYaoJiCanUseByType(uuid, yaojiType)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(uuid)
    if not myData then
        return 0
    end

    local defCnf = YjTreasureExcel.define[1]
    local yaojisData = myData.yaojis
    local nowCnt = yaojisData and yaojisData[yaojiType] and yaojisData[yaojiType].nowCnt or 0
    local useCnt = yaojisData and yaojisData[yaojiType] and yaojisData[yaojiType].useCnt or 0
    local yaoMax = defCnf.killYaoMax
    if yaojiType == YJ_YAOJI_CURE then
        yaoMax = defCnf.cureYaoMax
    else
        yaoMax = defCnf.killYaoMax
    end

    return yaoMax - useCnt > 0 and yaoMax - useCnt or 0
end

local function makeYjkillMonsterNet(net, uuid)
    local killMonsterData = YjTreasureDBLogic.getKillMonsterData(uuid)
    local conf = YjTreasureExcel.daBiaoReward
    local nowCnt = killMonsterData and killMonsterData.killCnt or 0
    local needCnt = getNeedKillMonsterCnt(uuid)
    net.state = 0
    if dabiaoIsGet(uuid, #conf) then
        if nowCnt > needCnt then
            nowCnt = needCnt
        end
    else
        if nowCnt >= needCnt then
            net.state = 1
        end
    end
    net.nowCnt = nowCnt
    net.needCnt = needCnt
end

function CG_YJTREASURE_QUERY(human, type)
    if not isOpen(human, true) then
        return
    end

    local defCnf = YjTreasureExcel.define[1]

    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData or not myData.objList then
        return Msg.send(Msg.gc.GC_YJTREASURE_SAVE_QUERY, human.fd)
    end

    local layerData = myData.layerData
    if not layerData then
        return Broadcast.sendErr(human, Lang.YJTREASURE_NOT_SET_POSE)
    end

    local dailyExtraSDTimes = YJ_GetTalismanAdd(human)

    local msgRet = Msg.gc.GC_YJTREASURE_QUERY
    msgRet.leftTime = getLeftTime()
    msgRet.nowLayer = layerData.layer
    msgRet.type = type and type or 0
    msgRet.heroList[0] = 0
    msgRet.layerMax = myData.layerMax or 0
    if myData.objList then
        for pos, obj in pairs(myData.objList) do
            msgRet.heroList[0] = msgRet.heroList[0] + 1
            local index = msgRet.heroList[0]
            makeHeroNet(msgRet.heroList[index], obj, pos, human)
        end
    end
    msgRet.isQuick = human.db.combatQuick[CombatDefine.COMBAT_TYPE10] or 0
    --require("common.Util").printTable(msgRet.heroList)
    msgRet.gridList[0] = 0
    if layerData.grids then
        for index = 1, YJ_TREASURE_GRID_MAX do
            local grid = layerData.grids[index]
            if grid then
                msgRet.gridList[0] = msgRet.gridList[0] + 1
                makeYjGridNet(human, msgRet.gridList[msgRet.gridList[0]], index, grid)
            end
        end
    end
    --require("common.Util").printTable(msgRet.gridList)
    makeYjkillMonsterNet(msgRet.killMonster, human.db._id)

    msgRet.yaojis[0] = YJ_YAOJI_KILL
    local yaojisData = myData.yaojis
    for yaoType = 1, YJ_YAOJI_KILL do
        local yaoItem = defCnf.cureYaoItem
        local nowCnt = yaojisData and yaojisData[yaoType] and yaojisData[yaoType].nowCnt or 0
        if yaoType == YJ_YAOJI_KILL then
            yaoItem = defCnf.killYaoItem
        end
        msgRet.yaojis[yaoType].yaojiType = yaoType
        Grid.makeItem(msgRet.yaojis[yaoType].item, yaoItem, nowCnt)
        msgRet.yaojis[yaoType].canUse = getYaoJiCanUseByType(human.db._id, yaoType)
    end
    --require("common.Util").printTable(msgRet.yaojis)
    msgRet.yjShoperCnt = myData.yjShoperCnt or 0

    msgRet.saodangMax = defCnf.saodangMax + dailyExtraSDTimes
    msgRet.saodangNow = myData.sangdang or 0

    local zhandouli = myData.rolebase.zhandouli
    local saodangNeed = 0
    if zhandouli < defCnf.saodangNeed then
        saodangNeed = defCnf.saodangNeed
    end
    msgRet.sangdangNeed = saodangNeed

    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

-- 是否跳过
function getQuick(human, combatType)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData or not myData.objList then
        return 0
    end

    local layerData = myData.layerData
    local nowLayer = layerData.layer
    if nowLayer < YJ_TREASURE_QUICK_MAX then
        return 0
    end
    return 1
end

--点击格子
function CG_YJTREASURE_TOUCH_GRID(human, gridIndex)
    if not isOpen(human, true) then
        return
    end

    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData then
        return Broadcast.sendErr(human, Lang.YJTREASURE_NOT_SET_POSE)
    end

    local layerData = myData.layerData
    if not layerData then
        return
    end

    local grids = layerData.grids
    local gridData = grids[gridIndex]

    if not gridData.isOpen then
        return Broadcast.sendErr(human, Lang.YJTREASURE_NOT_OPEN)
    end
    if gridData.gridType == YJ_TREASURE_GRID_TREASURE_SHOP then
        GC_YJTREASURE_TREASURESHOP(human, gridData)
    elseif gridData.gridType == YJ_TREASURE_GRID_SOUL then --
        GC_YJTREASURE_SOUL(human, gridIndex, gridData)
    elseif gridData.gridType == YJ_TREASURE_GRID_QUESTION then --
        GC_YJTREASURE_QUESTION(human, gridIndex, gridData, layerData.layer)
    elseif gridData.gridType == YJ_TREASURE_GRID_DICE then
        GC_YJTREASURE_DICE_QUERY(human)
    elseif gridData.gridType == YJ_TREASURE_GRID_BOX then
        GC_YJTREASURE_BOXREWARD(human)
    elseif gridData.gridType == YJ_TREASURE_GRID_KEY then
        getBoxRewardKey(human, gridIndex, grids)
    elseif gridData.gridType == YJ_TREASURE_GRID_DOOR then
        yjTreasure2NextLayer(human)
    end
end

--更新格子信息 grids[1].gridindex grids[1].gridData
function GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, grid)
    local msgRet = Msg.gc.GC_YJTREASURE_GRIDS_CHANGE
    makeYjGridNet(human, msgRet.grid, gridIndex, grid)
    Msg.send(msgRet, human.fd)
end

local function getShopItemByAllShoperID(uuid, allShopID)
    local allShopData = YjTreasureDBLogic.getAllShopData(uuid)
    if not allShopData then
        return
    end

    return allShopData[allShopID]
end

local function makeYjShoperItemNet(net, uuid, allShopID, shopItem, conf)
    local itemID = conf.item[1]
    local itemCnt = conf.item[2]
    Grid.makeItem(net.item, itemID, itemCnt)

    net.allShopID = allShopID

    local needItemID = conf.buyCost[1]
    local needItemCnt = conf.buyCost[2]
    Grid.makeItem(net.needItem, needItemID, needItemCnt)
    net.discount = conf.discountShow
    net.isBuy = shopItem.isBuy and 1 or 0
end

--打开格子内商店界面
function GC_YJTREASURE_TREASURESHOP(human, gridData)
    local msgRet = Msg.gc.GC_YJTREASURE_TREASURESHOP
    local treasureShop = gridData.treasureShop
    if not treasureShop then
        return
    end

    local treasureShopCnf = YjTreasureExcel.treasureShop
    msgRet.items[0] = #treasureShop
    for i = 1, #treasureShop do
        local allShopID = treasureShop[i]
        local shopItem = getShopItemByAllShoperID(human.db._id, allShopID)
        local shopConfID = shopItem.shopConfID
        local conf = treasureShopCnf[shopConfID]

        makeYjShoperItemNet(msgRet.items[i], human.db._id, allShopID, shopItem, conf)
    end

    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

local function canBuyByAllShopID(human, allShopID, noSend)
    local allShopData = YjTreasureDBLogic.getAllShopData(human.db._id)
    if not allShopData or not allShopData[allShopID] then
        if not noSend then
            Broadcast.sendErr(human, Lang.YJTREASURE_ALLSHOPER_ERR)
        end

        return
    end

    if allShopData[allShopID].isBuy then
        if not noSend then
            Broadcast.sendErr(human, Lang.YJTREASURE_BUY_HAD)
        end

        return
    end

    return true
end

local function buyItemByAllShopID(human, allShopID)
    local shopConf = YjTreasureExcel.treasureShop
    local shopItem = getShopItemByAllShoperID(human.db._id, allShopID)
    if shopItem.shopType == YJ_TREASURE_GRID_YJSHOPER then
        shopConf = YjTreasureExcel.yjShoper
    end
    local shopConfID = shopItem.shopConfID
    local conf = shopConf[shopConfID]
    local needItemID = conf.buyCost[1]
    local needItemCnt = conf.buyCost[2]
    local nowCnt = BagLogic.getItemCnt(human, needItemID)
    if nowCnt < needItemCnt then
        return Broadcast.sendErr(human, Lang.YJTREASURE_BUY_NEED_ERR)
    end

    BagLogic.delItem(human, needItemID, needItemCnt, "yj_treasure")

    YjTreasureDBLogic.setShopItemBuy(human.db._id, allShopID)

    local itemID = conf.item[1]
    local itemCnt = conf.item[2]
    --	BagLogic.addItem(human,itemID,itemCnt,"yj_treasure")
    BagLogic.cleanMomentItemList()
    BagLogic.updateMomentItem(1, itemID, itemCnt)
    BagLogic.addMomentItemList(human, "yj_treasure")

    return true
end

--购买格子内商店商品
function CG_YJTREASURE_TREASURESHOP_BUY(human, allShopID)
    if not canBuyByAllShopID(human, allShopID) then
        return
    end

    if not buyItemByAllShopID(human, allShopID) then
        return
    end

    local msgRet = Msg.gc.GC_YJTREASURE_TREASURESHOP_BUY
    msgRet.allShopID = allShopID
    Msg.send(msgRet, human.fd)
end

--灵魂拷问 打开界面
function GC_YJTREASURE_SOUL(human, gridIndex, gridData)
    local soulID = gridData.soul
    if not soulID then
        soulID = YjTreasureDBLogic.makeSoul(human.db._id, gridIndex)
    end

    local soulCnf = YjTreasureExcel.soul[soulID]
    local msgRet = Msg.gc.GC_YJTREASURE_SOUL
    msgRet.soulID = soulID
    msgRet.soulquestion = soulCnf.question
    msgRet.select1 = soulCnf.answer1
    msgRet.select2 = soulCnf.answer2

    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--回答灵魂拷问
function CG_YJTREASURE_SOUL_SELECT(human, gridIndex, answer)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    if not layerData or not layerData.grids then
        return
    end

    local gridData = layerData.grids[gridIndex]
    if not gridData then
        return
    end

    if gridData.gridType ~= YJ_TREASURE_GRID_SOUL then
        return
    end

    local soulID = gridData.soul
    if not soulID then
        return
    end

    local layerCnf = YjTreasureExcel.layer[layerData.layer]
    local soulRewards = layerCnf.soulRewards
    local totalWeight = 0
    for i = 1, #soulRewards do
        totalWeight = totalWeight + soulRewards[i][3]
    end
    local rand = math.random(1, totalWeight)
    local weight = 0

    local getList = {}
    for i = 1, #soulRewards do
        weight = weight + soulRewards[i][3]
        if rand <= weight then
            local itemID = soulRewards[i][1]
            local itemCnt = soulRewards[i][2]

            getList[#getList + 1] = {}
            getList[#getList][1] = itemID
            getList[#getList][2] = itemCnt
            BagLogic.addItem(human, itemID, itemCnt, "yj_treasure_kaowen")
            layerData.getItems = layerData.getItems or {}
            layerData.getItems[itemID] = (layerData.getItems[itemID] or 0) + itemCnt
            break
        end
    end
    gridData = YjTreasureDBLogic.gridTypeChange(human.db._id, layerData.grids, gridIndex, YJ_TREASURE_GRID_KONGDI, true)
    YjTreasureDBLogic.updateLayerData(human.db._id, layerData)

    local soulCnf = YjTreasureExcel.soul[soulID]
    local msgRet = Msg.gc.GC_YJTREASURE_SOUL_SELECT
    local tip = soulCnf.tips1
    if answer == 2 then
        tip = soulCnf.tips2
    end
    msgRet.tip = tip
    msgRet.items[0] = 0
    for k, v in ipairs(getList) do
        Grid.makeItem(msgRet.items[k], v[1], v[2])
    end
    msgRet.items[0] = #getList
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)

    GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, gridData)
end

--博文强识 打开界面
local function makeYjQuestionNet(net, questionID, answer)
    local questionCnf = YjTreasureExcel.question[questionID]
    net.questionID = questionID
    net.question = questionCnf.question
    net.select1 = questionCnf.select1
    net.select2 = questionCnf.select2
    net.select3 = questionCnf.select3
    net.select4 = questionCnf.select4
    net.rightSelect = questionCnf.rightSelect
    net.answer = answer and answer[questionID] or 0
end

function GC_YJTREASURE_QUESTION(human, gridIndex, gridData, layer)
    local questionData = gridData.question
    if not questionData then
        questionData = YjTreasureDBLogic.makeQuestion(human.db._id, gridIndex)
    end

    local msgRet = Msg.gc.GC_YJTREASURE_QUESTION
    msgRet.yjQuestions[0] = #questionData.list
    for i = 1, #questionData.list do
        makeYjQuestionNet(msgRet.yjQuestions[i], questionData.list[i], questionData.answer)
    end

    local layCnf = YjTreasureExcel.layer[layer]
    local questionReward = layCnf.questionReward
    msgRet.oneReward[0] = #questionReward
    for i = 1, #questionReward do
        Grid.makeItem(msgRet.oneReward[i], questionReward[i][1], questionReward[i][2])
    end

    msgRet.rightCnt = questionData.rightCnt or 0

    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--博闻强识 回答问题
function CG_YJTREASURE_QUESTION_SELECT(human, gridIndex, questionID, answer)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    if not layerData or not layerData.grids then
        return
    end

    local gridData = layerData.grids[gridIndex]
    if not gridData then
        return
    end

    if gridData.gridType ~= YJ_TREASURE_GRID_QUESTION then
        return
    end

    local questionCnf = YjTreasureExcel.question[questionID]
    if not questionCnf then
        return
    end

    local questionData = gridData.question
    if questionData and questionData.answer and questionData.answer[questionID] then
        return
    end

    questionData.answer = questionData.answer or {}
    questionData.answer[questionID] = answer

    if questionCnf.rightSelect == answer then
        questionData.rightCnt = (questionData.rightCnt or 0) + 1
        local layCnf = YjTreasureExcel.layer[layerData.layer]
        local questionReward = layCnf.questionReward
        for i = 1, #questionReward do
            local itemID = questionReward[i][1]
            local itemCnt = questionReward[i][2]
            gridData.getItems = gridData.getItems or {}
            gridData.getItems[itemID] = (gridData.getItems[itemID] or 0) + itemCnt
            layerData.getItems = layerData.getItems or {}
            layerData.getItems[itemID] = (layerData.getItems[itemID] or 0) + itemCnt
        end
    end

    if questionData.list[#questionData.list] == questionID then
        BagLogic.addItemList(human, gridData.getItems, "yj_treasure")
        gridData =
            YjTreasureDBLogic.gridTypeChange(human.db._id, layerData.grids, gridIndex, YJ_TREASURE_GRID_KONGDI, true)

        GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, gridData)
    end

    YjTreasureDBLogic.updateLayerData(human.db._id, layerData)

    local msgRet = Msg.gc.GC_YJTREASURE_QUESTION_SELECT
    msgRet.gridIndex = gridIndex
    msgRet.questionID = questionID
    msgRet.rightCnt = questionData.rightCnt or 0
    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--好运骰子 打开界面
function GC_YJTREASURE_DICE_QUERY(human)
    local defCnf = YjTreasureExcel.define[1]
    local msgRet = Msg.gc.GC_YJTREASURE_DICE_QUERY
    msgRet.zuanshi = defCnf.diceZuanShiCost
    msgRet.jinbi = defCnf.diceJinBiCost
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--好运骰子 选择消耗
function CG_YJTREASURE_DICE_USE(human, use, gridIndex)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    if not layerData or not layerData.grids then
        return
    end

    local gridData = layerData.grids[gridIndex]
    if not gridData then
        return
    end

    if gridData.gridType ~= YJ_TREASURE_GRID_DICE then
        return
    end

    local defCnf = YjTreasureExcel.define[1]
    if use == YJ_DICE_JINBI then
        if human.db.jinbi < defCnf.diceJinBiCost then
            return Broadcast.sendErr(human, Lang.COMMON_NO_JINBI)
        end
        ObjHuman.updateJinbi(human, -defCnf.diceJinBiCost, "yj_treasure")
    else
        if not ObjHuman.checkRMB(human, defCnf.diceZuanShiCost) then
            return
        end
        ObjHuman.decZuanshi(human, -defCnf.diceZuanShiCost, "yj_treasure")
    end

    local totalWeight = 0
    for i = 1, #defCnf.diceWeight do
        totalWeight = totalWeight + defCnf.diceWeight[i][2]
    end

    local rand = math.random(1, totalWeight)
    local weight = 0
    local content = ""
    for i = 1, #defCnf.diceWeight do
        weight = weight + defCnf.diceWeight[i][2]
        if rand <= weight then
            local bei = defCnf.diceWeight[i][1]
            local itemID = nil
            local cnt = nil
            if use == YJ_DICE_JINBI then
                itemID = ItemDefine.ITEM_JINBI_ID
                cnt = defCnf.diceJinBiCost * bei
                ObjHuman.updateJinbi(human, cnt, "yj_treasure")
            else
                itemID = ItemDefine.ITEM_ZUANSHI_ID
                cnt = defCnf.diceZuanShiCost * bei
                ObjHuman.addZuanshi(human, cnt, "yj_treasure")
            end
            if cnt then
                local itemName = ItemDefine.getValue(itemID, "name")
                content = Util.format(Lang.YJTREASURE_DICE_GET, bei, itemName, cnt)

                layerData.getItems = layerData.getItems or {}
                layerData.getItems[itemID] = (layerData.getItems[itemID] or 0) + cnt
            end
            break
        end
    end

    gridData = YjTreasureDBLogic.gridTypeChange(human.db._id, layerData.grids, gridIndex, YJ_TREASURE_GRID_KONGDI, true)
    YjTreasureDBLogic.updateLayerData(human.db._id, layerData)
    local msgRet = Msg.gc.GC_YJTREASURE_DICE_USE
    msgRet.content = content
    Msg.send(msgRet, human.fd)

    GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, gridData)
end

--宝箱 打开界面
function GC_YJTREASURE_BOXREWARD(human)
    local defCnf = YjTreasureExcel.define[1]

    local msgRet = Msg.gc.GC_YJTREASURE_BOXREWARD
    local boxReward = defCnf.boxReward
    msgRet.yjBoxReward[0] = #boxReward
    for i = 1, #boxReward do
        Grid.makeItem(msgRet.yjBoxReward[i], boxReward[i][1], boxReward[i][2])
    end
    Grid.makeItem(msgRet.need, defCnf.keyItemID, defCnf.keyNeed)

    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--宝箱 开启
function CG_YJTREASURE_BOXREWARD_OPEN(human, gridIndex)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    if not layerData or not layerData.grids then
        return
    end

    local gridData = layerData.grids[gridIndex]
    if not gridData then
        return
    end

    if gridData.gridType ~= YJ_TREASURE_GRID_BOX then
        return
    end

    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    local defCnf = YjTreasureExcel.define[1]
    local nowKey = BagLogic.getItemCnt(human, defCnf.keyItemID)
    local keyNeed = defCnf.keyNeed
    if keyNeed > nowKey then
        return Broadcast.sendErr(human, Lang.YJTREASURE_BOX_KEY_ERR)
    end

    BagLogic.delItem(human, defCnf.keyItemID, 1, "yj_treasure")

    local boxReward = defCnf.boxReward
    local totalWeight = 0
    for i = 1, #boxReward do
        totalWeight = totalWeight + boxReward[i][3]
    end

    local rand = math.random(1, totalWeight)
    local weight = 0
    BagLogic.cleanMomentItemList()
    for i = 1, #boxReward do
        weight = weight + boxReward[i][3]
        if rand <= weight then
            local itemID = boxReward[i][1]
            local itemCnt = boxReward[i][2]
            BagLogic.updateMomentItem(1, itemID, itemCnt)
            --	BagLogic.addItem(human,itemID,itemCnt,"yj_treasure")
            Broadcast.sendErr(human, Lang.YJTREASURE_BOX_OPEN)

            layerData.getItems = layerData.getItems or {}
            layerData.getItems[itemID] = (layerData.getItems[itemID] or 0) + itemCnt
            break
        end
    end
    BagLogic.addMomentItemList(human, "yj_treasure")
    gridData = YjTreasureDBLogic.gridTypeChange(human.db._id, layerData.grids, gridIndex, YJ_TREASURE_GRID_KONGDI, true)
    YjTreasureDBLogic.updateLayerData(human.db._id, layerData)

    GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, gridData)

    Msg.send(Msg.gc.GC_YJTREASURE_BOXREWARD_OPEN, human.fd)
end

--点击钥匙格子
function getBoxRewardKey(human, gridIndex, grids)
    local defCnf = YjTreasureExcel.define[1]
    --	BagLogic.addItem(human,defCnf.keyItemID,1,"yj_treasure")
    BagLogic.cleanMomentItemList()
    BagLogic.updateMomentItem(1, defCnf.keyItemID, 1)
    BagLogic.addMomentItemList(human, "yj_treasure")
    YjTreasureDBLogic.gridTypeChange(human.db._id, grids, gridIndex, YJ_TREASURE_GRID_KONGDI, true)
    YjTreasureDBLogic.updateGridsData(human.db._id, grids)

    GC_YJTREASURE_GRIDS_CHANGE(human, gridIndex, grids[gridIndex])
end

--前往下一层
function yjTreasure2NextLayer(human)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    local layCnf = YjTreasureExcel.layer
    local nowLayer = layerData.layer

    if nowLayer >= #layCnf then
        return Broadcast.sendErr(human, Lang.YJTREASURE_LAYER_ERR)
    end

    GC_YJTREASURE_GETITEMS(human)

    local roleData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    local layerMax = roleData.layerMax or 0
    if layerMax < nowLayer + 1 then
        roleData.layerMax = nowLayer + 1
        YjTreasureDBLogic.updateUuid2Role(roleData)
    end

    YjTreasureDBLogic.creatLayerDataByUuid(human.db._id, nowLayer + 1)

    MengxinLogic.onCallBack(human, MengxinLogic.MX_TASK_TYPE_16, nowLayer + 1)
    --TODO:记录遗迹探险
    --Log.write(Log.LOGID_OSS_BATTLE_RELIC, human.db._id, human.db.account, human.db.name, nowLayer + 1)
    Log.write(Log.LOGID_OSS_BATTLE_RELIC, human.db._id, human.db.newUniqueTag, human.db.name, nowLayer + 1)

    YunYingLogic.onCallBack(human, "YJTreasurePass", 1)
    TriggerLogic.PublishEvent(TriggerDefine.YJTREASURE_PASS_LEVEL, human.db._id, 1)
    CG_YJTREASURE_QUERY(human, 1)
end

--奖励收益弹窗
function GC_YJTREASURE_GETITEMS(human, noSend)
    local roleData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    local layerData = YjTreasureDBLogic.getLayerDataByUuid(human.db._id)
    local layCnf = YjTreasureExcel.layer
    local nowLayer = layerData.layer

    if nowLayer >= #layCnf then
        Broadcast.sendErr(human, Lang.YJTREASURE_LAYER_ERR)
    end

    local msgRet = Msg.gc.GC_YJTREASURE_GETITEMS
    msgRet.getItems[0] = 0
    for itemID, itemCnt in pairs(roleData.item) do
        msgRet.getItems[0] = msgRet.getItems[0] + 1
        local index = msgRet.getItems[0]
        Grid.makeItem(msgRet.getItems[index], itemID, itemCnt)
    end
    Msg.send(msgRet, human.fd)
end

--点击神秘商人次数 获得权重商品 即进入全部商品列表
function CG_YJTREASURE_YJSHOPER(human)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    local yjShoperCnt = myData.yjShoperCnt or 0
    if yjShoperCnt < 1 then
        return Broadcast.sendErr(human, Lang.YJTREASURE_YJSHOPER_ERR)
    end

    myData.yjShoperCnt = yjShoperCnt - 1
    YjTreasureDBLogic.updateUuid2Role(myData)

    local allShopID, yjShoperCnfID = YjTreasureDBLogic.makeYjShoperItem(human.db._id)
    local yjShoperCnf = YjTreasureExcel.yjShoper[yjShoperCnfID]

    local msgRet = Msg.gc.GC_YJTREASURE_YJSHOPER
    local shopItem = getShopItemByAllShoperID(human.db._id, allShopID)
    makeYjShoperItemNet(msgRet.yjShoperItem, human.db._id, allShopID, shopItem, yjShoperCnf)
    msgRet.yjShoperCnt = myData.yjShoperCnt
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--神秘商人商品购买
function CG_YJTREASURE_YJSHOPER_BUY(human, allShopID)
    if not canBuyByAllShopID(human, allShopID) then
        return
    end

    if not buyItemByAllShopID(human, allShopID) then
        return
    end

    local msgRet = Msg.gc.GC_YJTREASURE_YJSHOPER_BUY
    msgRet.allShopID = allShopID
    Msg.send(msgRet, human.fd)
end

--探险商城（包含神秘商人和商店所出现的所有道具）
--商品小于100个发送全部商品
--商品大于100个，只发送未购买的
function CG_YJTREASURE_ALLSHOP(human)
    local msgRet = Msg.gc.GC_YJTREASURE_ALLSHOP
    msgRet.itemList[0] = 0
    msgRet.isEnd = 0

    local allShopData = YjTreasureDBLogic.getAllShopData(human.db._id)
    if not allShopData then
        msgRet.isEnd = 1
        Msg.send(msgRet, human.fd)
        return
    end

    local treasureShopCnf = YjTreasureExcel.treasureShop
    local yjShoperCnf = YjTreasureExcel.yjShoper
    local count = 0
    for allShopID = 1, #allShopData do
        if msgRet.itemList[0] >= #msgRet.itemList then
            count = 0
            Msg.send(msgRet, human.fd)
        end

        local shopItem = allShopData[allShopID]
        local conf = treasureShopCnf[shopItem.shopConfID]
        if shopItem.shopType == YJ_SHOP_YJSHOPER then
            conf = yjShoperCnf[shopItem.shopConfID]
        end

        if #allShopData <= YJ_SHOP_ALLSHOP_SEND_MAX then
            count = count + 1
            local index = count
            makeYjShoperItemNet(msgRet.itemList[index], human.db._id, allShopID, shopItem, conf)
        else
            if not shopItem.isBuy then
                count = count + 1
                local index = count
                makeYjShoperItemNet(msgRet.itemList[index], human.db._id, allShopID, shopItem, conf)
            end
        end
        msgRet.itemList[0] = count
    end
    msgRet.isEnd = 1
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--探险商城 购买
function CG_YJTREASURE_ALLSHOP_BUY(human, allShopID)
    if not canBuyByAllShopID(human, allShopID) then
        return
    end

    if not buyItemByAllShopID(human, allShopID) then
        return
    end

    local msgRet = Msg.gc.GC_YJTREASURE_ALLSHOP_BUY
    msgRet.allShopID = allShopID
    Msg.send(msgRet, human.fd)
end

--buff 加成
function CG_YJTREASURE_BUFF_QUERY(human)
    local buffData = YjTreasureDBLogic.getBuffData(human.db._id)
    if not buffData then
        return
    end

    local msgRet = Msg.gc.GC_YJTREASURE_BUFF_QUERY
    msgRet.attrs[0] = 0
    for key, value in pairs(buffData) do
        msgRet.attrs[0] = msgRet.attrs[0] + 1
        local index = msgRet.attrs[0]
        msgRet.attrs[index].attr.key = key
        msgRet.attrs[index].attr.value = value
    end

    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--点击目标奖励
--有可领取时，可领奖励全领取，刷新消灭守卫信息
--没有可领取时，返回列表信息
function CG_YJTREASURE_DABIAOREWARD(human)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    local nowCnt = myData.killMonster and myData.killMonster.killCnt or 0
    local daBiaoRewardCnf = YjTreasureExcel.daBiaoReward
    local totalReward = nil
    for i = 1, #daBiaoRewardCnf do
        if not dabiaoIsGet(human.db._id, i) then
            local needCnt = daBiaoRewardCnf[i].needCnt
            if nowCnt >= needCnt then
                myData.killMonster.getList = myData.killMonster.getList or {}
                myData.killMonster.getList[i] = i

                local reward = daBiaoRewardCnf[i].reward
                totalReward = totalReward or {}
                for i = 1, #reward do
                    totalReward[reward[i][1]] = (totalReward[reward[i][1]] or 0) + reward[i][2]
                end
            end
        end
    end

    if totalReward then
        BagLogic.addItemList(human, totalReward, "yj_treasure")
        YjTreasureDBLogic.updateUuid2Role(myData)

        GC_YJTREASURE_DABIAOREWARD_CHANGE(human)
    else
        GC_YJTREASURE_DABIAOREWARD_QUERY(human)
    end
end

function GC_YJTREASURE_DABIAOREWARD_CHANGE(human)
    local msgRet = Msg.gc.GC_YJTREASURE_DABIAOREWARD_CHANGE
    makeYjkillMonsterNet(msgRet.killMonster, human.db._id)
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

function GC_YJTREASURE_DABIAOREWARD_QUERY(human)
    local daBiaoRewardCnf = YjTreasureExcel.daBiaoReward
    local msgRet = Msg.gc.GC_YJTREASURE_DABIAOREWARD_QUERY
    msgRet.dabiaoList[0] = #daBiaoRewardCnf
    for i = 1, #daBiaoRewardCnf do
        msgRet.dabiaoList[i].desc = daBiaoRewardCnf[i].name
        msgRet.dabiaoList[i].needCnt = daBiaoRewardCnf[i].needCnt
        msgRet.dabiaoList[i].isget = dabiaoIsGet(human.db._id, i) and 1 or 0

        local reward = daBiaoRewardCnf[i].reward
        msgRet.dabiaoList[i].items[0] = #reward
        for j = 1, #reward do
            Grid.makeItem(msgRet.dabiaoList[i].items[j], reward[j][1], reward[j][2])
        end
    end

    local killMonsterData = YjTreasureDBLogic.getKillMonsterData(human.db._id)
    msgRet.nowCnt = killMonsterData and killMonsterData.killCnt or 0

    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--排行榜
local function makeYjBoardNet(net, rank, uuid)
    net.rank = rank
    if rank > YJ_TREASURE_BILLBOARD_SHOW then
        net.rank = 0
    end

    local roleData = YjTreasureDBLogic.getRoleDataByUuid(uuid)
    RoleLogic.makeRoleBase(roleData.rolebase, net.roleBase)

    local layerData = YjTreasureDBLogic.getLayerDataByUuid(uuid)
    net.layer = layerData and layerData.layer or 0
    net.tansuo = roleData.tansuo or 0
end
function CG_YJTREASURE_BILLBOARD(human)
    local msgRet = Msg.gc.GC_YJTREASURE_BILLBOARD
    local rank2Uuid = YjTreasureDBLogic.getDBrank2Uuid()
    msgRet.yjBoard[0] = 0
    for i = 1, #rank2Uuid do
        if msgRet.yjBoard[0] < #msgRet.yjBoard then
            msgRet.yjBoard[0] = msgRet.yjBoard[0] + 1
            makeYjBoardNet(msgRet.yjBoard[i], i, rank2Uuid[i])
        end
    end

    local myRank = YjTreasureDBLogic.getRankByUuid(human.db._id)
    makeYjBoardNet(msgRet.myRank, myRank, human.db._id)
    --	Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--使用药剂
function CG_YJTREASURE_USE_YAOJI(human, yaojiType, index)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData then
        return
    end

    local defCnf = YjTreasureExcel.define[1]
    local yaojisData = myData.yaojis
    local nowCnt = yaojisData and yaojisData[yaojiType] and yaojisData[yaojiType].nowCnt or 0
    local useCnt = yaojisData and yaojisData[yaojiType] and yaojisData[yaojiType].useCnt or 0

    local yaoMax = defCnf.killYaoMax
    local content1 = Lang.YJTREASURE_YAOJI2_ERR_MAX
    local content2 = Lang.YJTREASURE_YAOJI2_ERR_CNT
    if yaojiType == YJ_YAOJI_CURE then
        yaoMax = defCnf.cureYaoMax
        content2 = Lang.YJTREASURE_YAOJI1_ERR_CNT
        if useCnt >= yaoMax then
            content1 = Lang.YJTREASURE_YAOJI1_ERR_MAX
            return Broadcast.sendErr(human, content1)
        end
    end

    if nowCnt < 1 then
        return Broadcast.sendErr(human, content2)
    end

    if yaojiType == YJ_YAOJI_CURE then
        local objList = myData.objList
        if not objList[index] then
            return
        end

        local obj = objList[index]
        local hpMax = YjTreasureDBLogic.getCombatObjHpMax(obj)
        local hp = YjTreasureDBLogic.getCombatObjHp(obj)
        if hp == hpMax then
            return Broadcast.sendErr(human, Lang.YJTREASURE_YAOJI_CURE_ERR1)
        end
        if hp <= 0 then
            return Broadcast.sendErr(human, Lang.YJTREASURE_YAOJI_CURE_ERR2)
        end
        if obj then
            myData.yaojis[yaojiType].nowCnt = nowCnt - 1
            myData.yaojis[yaojiType].useCnt = useCnt + 1

            myData.objList[index].hp = hp + math.floor(hpMax * 0.5)
            if myData.objList[index].hp > hpMax then
                myData.objList[index].hp = hpMax
            end
            YjTreasureDBLogic.updateUuid2Role(myData)

            local msgRet = Msg.gc.GC_YJTREASURE_USE_YAOJI
            msgRet.type = yaojiType
            msgRet.canUse = getYaoJiCanUseByType(human.db._id, yaojiType)
            makeHeroNet(msgRet.obj, obj, index, human)
            Msg.send(msgRet, human.fd)
            CG_YJTREASURE_QUERY(human, 1)
        end
    else
        local gridsData = YjTreasureDBLogic.getGridsData(human.db._id)
        local gridData = gridsData[index]
        if not gridData then
            return
        end

        if gridData.gridType ~= YJ_TREASURE_GRID_BOSS and gridData.gridType ~= YJ_TREASURE_GRID_MONSTER then
            return
        end

        myData.yaojis[yaojiType].nowCnt = nowCnt - 1
        myData.yaojis[yaojiType].useCnt = useCnt + 1

        local monsterObjList = gridData.monsterObjList
        local send = nil
        for pos in pairs(monsterObjList) do
            if monsterObjList[pos] then
                monsterObjList[pos].hp = 0
                YjTreasureDBLogic.updateGridsData(human.db._id, gridsData)

                send = true
                YjTreasureCombat.killMonsterOpenGrids(human, index)
            end
        end

        if send then
            Broadcast.sendErr(human, Lang.YJTREASURE_YAOJI_USE_OK)
            CG_YJTREASURE_QUERY(human, 1)
            LiLianLogic.onCallback(human, LiLianLogic.LILIAN_OUTID13, 1)
            HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE20, 1)
        end
    end
end

function yjYaoJiAdd(human, value, yaojiType)
    if not isOpen(human) then
        return
    end

    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData then
        return
    end

    myData.yaojis = myData.yaojis or {}
    myData.yaojis[yaojiType] = myData.yaojis[yaojiType] or {}
    myData.yaojis[yaojiType].nowCnt = (myData.yaojis[yaojiType].nowCnt or 0) + value

    YjTreasureDBLogic.updateUuid2Role(myData)

    local defCnf = YjTreasureExcel.define[1]
    local msgRet = Msg.gc.GC_YJTREASURE_YAOJI_ADD
    local yaoItem = defCnf.cureYaoItem
    local nowCnt = myData.yaojis[yaojiType].nowCnt
    if yaojiType == YJ_YAOJI_KILL then
        yaoItem = defCnf.killYaoItem
    end
    msgRet.yaoji.yaojiType = yaojiType
    Grid.makeItem(msgRet.yaoji.item, yaoItem, nowCnt)
    msgRet.yaoji.canUse = getYaoJiCanUseByType(human.db._id, yaojiType)
    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

--- 外部接口 ---
function getLayerMax(human)
    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData then
        return 0
    end

    return myData.layerMax or 0
end

function isDot(human)
    if not isOpen(human, true) then
        return
    end

    local myData = YjTreasureDBLogic.getRoleDataByUuid(human.db._id)
    if not myData or not myData.objList then
        return true
    end
    return
end
