--------------------------------------------------- -- 过关斩将/圣树试炼 --------------------------------------------------- --[[ db.drill = { time = 1, -- 这次数据的时间 diff = 1, -- 选择的难度 drillId = 1, -- 今日最大 通关关卡 maxDiff = 1, -- 最大通关难度 lastDiff = 1, -- 昨日选择的难度 lastDrillId = 1, -- 昨日最大关卡 myHelpIndex = 1, -- 我选择的援助出去英雄 helpoutList = {}, -- 我选择的援助英雄 dayGet = {}, -- 今日已获得奖励 boxGet = {}, -- 今日宝箱 已领取 } ]]-- local Config = require("Config") local DrillExcel = require("excel.drill") local MailExcel = require("excel.mail") local MonsterExcel = require("excel.monster") local Util = require("common.Util") local Lang = require("common.Lang") local CommonDB = require("common.CommonDB") local Msg = require("core.Msg") local InnerMsg = require("core.InnerMsg") local ObjHuman = require("core.ObjHuman") local Timer = require("core.Timer") local Broadcast = require("broadcast.Broadcast") local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local CombatImpl = require("combat.CombatImpl") local CombatObj = require("combat.CombatObj") local CombatLogic = require("combat.CombatLogic") local CombatDefine = require("combat.CombatDefine") local CombatPosLogic = require("combat.CombatPosLogic") local CopyManage = require("copy.CopyManage") local ChatPaoMaLogic = require("chat.ChatPaoMaLogic") local DrillDB = require("drill.DrillDB") local DrillMiddleLogic = require("drill.DrillMiddleLogic") local DrillLogicAttribute = require("drill.DrillLogicAttribute") local HeroGrid = require("hero.HeroGrid") local HeroDefine = require("hero.HeroDefine") local RoleDefine = require("role.RoleDefine") local RoleLogic = require("role.RoleLogic") local RoleDBLogic = require("role.RoleDBLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local MailManager = require("mail.MailManager") local MiddleConnect = require("middle.MiddleConnect") local HeroExcel = require("excel.hero") local FriendDBLogic = require("friend.FriendDBLogic") local ChengjiuLogic = require("chengjiu.ChengjiuLogic") local ChengjiuDefine = require("chengjiu.ChengjiuDefine") local LiLianLogic = require("dailyTask.LiLianLogic") local BeSkill = require("combat.BeSkill") local SkinLogic = require("skin.SkinLogic") local DailyTaskLogic = require("dailyTask.DailyTaskLogic") local ItemDefine = require("bag.ItemDefine") local VipLogic = require("vip.VipLogic") local HeroLogic = require("hero.HeroLogic") local MailDefine = require("mail.MailIdDefine") local JibanLogic = require("combat.JibanLogic") local HeroLogLogic = require("absAct.HeroLogLogic") local HeroGrowUp = require("absAct.HeroGrowUp") local MengxinLogic = require("present.MengxinLogic") local YunYingLogic = require("yunying.YunYingLogic") local TalismanLogic = require("talisman.TalismanLogic") local WeekTaskLogic = require("dailyTask.WeekTaskLogic") local TriggerLogic = require("trigger.TriggerLogic") local TriggerDefine = require("trigger.TriggerDefine") local OverflowFundLogic = require("present.OverflowFundLogic") local Log = require("common.Log") local queryFields = {["uuid"] = 1} local queryFieldsList = {} local queryUuidFields = {["uuid"] = 1} local queryRawardFields = {["drillId"] = 1, ["rawardStatus"] = 1} local sortTable = {} SEASON_KEEP_DAY = 1 -- 1天一个流程 STATE_NOOPEN = 0 -- 未开始 STATE_OPEN = 1 -- 开始 STATE_READY = 2 -- 准备期间 -- 难度说明 DIFF_NORMAL = 1 -- 普通难度 DIFF_ELITE = 2 -- 精英难度 DIFF_INCUBI = 3 -- 噩梦难度 DRILL_BOX_STATE_0 = 0 -- 未领取 DRILL_BOX_STATE_1 = 1 -- 可领取 DRILL_BOX_STATE_2 = 2 -- 已领取 DRILL_BOX_GOD_MAX = 3 -- 诸神怜悯 最大获奖次数 local FRIEND_ITEM_CNT = 10 -- 每次助战获得x点友情点 local MAX_HEROCOMBAT_MUL = 150 -- 助战英雄最大倍数百分比 local INIT_HP_MAX = 100 local SAODANG_COND_LEVEL = 90 --勇者试炼副本扫荡所需等级 local CHALLENGE_DIAMONS = 500 -- 使用钻石通过当前关卡需要的钻石数量 --秘宝加成 local function getTalismanAdd(human) local heroExpMul = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.DRILL_HERO_EXP) or 0) / 100 return heroExpMul end -- 获取剩余时间 function getState() -- if MiddleConnect.IS_MIDDLE_CONNECT ~= true then -- return STATE_NOOPEN, Lang.MIDDLE_SVR_ERR_CONNECT -- end return STATE_OPEN end -- 判断 function isOpen(human, sendTip) --[[ local isok, tip = CopyManage.isOpen(CopyInfo, human) if not isok then if sendTip and tip then Broadcast.sendErr(human, tip) end return end local state, _, tip = getState() if state ~= STATE_OPEN then if sendTip and tip then Broadcast.sendErr(human, tip) end return end ]] return true end -- 活动开始倒计时 function getStartLeftTime(human) local state, leftSec = getState() if state ~= STATE_NOOPEN then return leftSec end return 0 end function getCopyState(human) local state = getState() return state end -- 最大通关难度 function getMaxDiff(human) if not human.db.drill then return 0 end return human.db.drill.maxDiff or 0 end function setMaxDiff(human, diff) if not human.db.drill then return end human.db.drill = human.db.drill or {} human.db.drill.maxDiff = diff end -- 获取关卡奖励配置 function getDrillItems(drillId, diff) local config = DrillExcel.drill[drillId] if not config then return end if diff == DIFF_NORMAL then return config.items end return config["items" .. diff] end -- 数据重置 -- 重置关卡数据 -- 重置关卡阵容 -- 每天0点检测是否开启了试炼 进行清除 function onHour() DrillDB.checkDrillReset() end function dayCheck() if _G.is_middle then return end DrillDB.reset() end -- 查询时间 function querySec(human) if not isOpen(human, true) then return end local state, leftSec = getState() local msgRet = Msg.gc.GC_DRILL_SEC msgRet.leftSec = leftSec msgRet.isStart = (state == STATE_OPEN) and 1 or 0 Msg.send(msgRet, human.fd) queryDrillId(human) end function inintDrill(human) if not human.db.drill then human.db.drill = {} local drill = human.db.drill drill.time = 0 drill.diff = 0 drill.drillId = nil drill.maxDiff = 0 drill.lastDiff = 0 drill.lastDrillId = 0 drill.myHelpIndex = 0 drill.dayGet = nil drill.boxGet = nil drill.myHelpHero = nil drill.helpoutList = nil end end function updateDaily(human) -- CombatPosLogic.cleanCombatHeros(human, CombatDefine.COMBAT_TYPE9) local drillDB = human.db.drill if not drillDB then return end if Util.isSameDay(drillDB.time) then return end local surDay = Util.diffDay(drillDB.time) if surDay == 1 then drillDB.lastDrillId = drillDB.drillId drillDB.lastDiff = drillDB.diff else drillDB.lastDrillId = 0 drillDB.lastDiff = 0 end drillDB.time = os.time() drillDB.drillId = nil drillDB.diff = 0 drillDB.dayGet = nil drillDB.boxGet = nil drillDB.myHelpIndex = 0 drillDB.myHelpHero = nil drillDB.helpoutList = nil drillDB.oneClickSaodangDone = nil -- 清除扫荡完成标记 end -- 修正 玩家DB 玩家卡0点 选择难度挑战 DrilDB 后清 导致 玩家DB 和 DrillDB 对不上 后续修改为 以DrillDB 为准 function fixDrillDB(human) if human.db.drill then human.db.drill.diff = 0 end end -- 难度选择查询 function diffChoseQuery(human) if not human.db.drill then inintDrill(human) end local drill = human.db.drill if not drill.diff or drill.diff == 0 then local msgRet = Msg.gc.GC_DRILL_DIFF msgRet.isGuide = drill.isGuide or 1 drill.isGuide = 0 for i = DIFF_NORMAL , DIFF_INCUBI do local config = DrillExcel.define[i] local net = msgRet.list[i] net.diff = i net.canChose = i == DIFF_NORMAL and 1 or 0 net.reward[0] = 0 net.needZhanli = config.needZhanli if drill.maxDiff >= i - 1 and human.db.zhandouli >= config.needZhanli then net.canChose = 1 end end msgRet.list[0] = DIFF_INCUBI Msg.send(msgRet, human.fd) end end function checkSaoDang(human, diff, lastDiff, lastId) local diff = diff local id = 1 local drillDB = human.db.drill if not drillDB then return diff, id end lastId = lastId and lastId or 0 lastId = lastId <= #DrillExcel.drill and lastId or #DrillExcel.drill local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204) local rewardCnt = double and 2 or 1 --秘宝加成 local heroExpMul = getTalismanAdd(human) if lastDiff and lastDiff == diff and lastId > 10 then id = lastId - 10 local itemInfo = {} for i = 1 , id do local drillItems = getDrillItems( i, lastDiff) -- 关卡奖励 for _, item in ipairs(drillItems) do local itemID = item[1] local itemCnt = item[2] * rewardCnt if itemID == ItemDefine.ITEM_GREEN_EXP_ID then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end drillDB.dayGet = drillDB.dayGet or {} drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt BagLogic.addItem(human, itemID, itemCnt, "drill") end end -- BagLogic.sendItemGetList(human, itemList, "drill") local msgRet = Msg.gc.GC_DRILL_SAODANG_ITEM msgRet.drillId = id local len = 0 for k , v in pairs(drillDB.dayGet) do len = len + 1 Grid.makeItem(msgRet.itemList[len], k, v) -- Grid.makeItem(msgRet.itemList[len], k, v, nil, nil, nil, nil, nil, nil, itemInfo[k]) end msgRet.itemList[0] = len msgRet.double = double and 1 or 0 Msg.send(msgRet, human.fd) id = id + 1 end return diff, id end function saodangQuest(human, drillId) if drillId <= 1 then return end local drill = human.db.drill if not drill then return end local diff = drill.diff local dirllDefConfig = DrillExcel.define[drill.diff] if not dirllDefConfig then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then fristQust(human, drillId) return end local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1) if zhandouli <= 0 then return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT) end if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手 zhandouli = human.maxZDL.zhandouli end local notTab = {} for i = 1 , drillId do local drillObj = pipei(human, i, diff, zhandouli, notTab) drillData.drillObjs[i] = Util.copyTable(drillObj) end DrillDB.updateDrillData(drillData) end -- 选择难度 function choseDiff(human, diff) if not human.db.drill then inintDrill(human) end local drill = human.db.drill local now = os.time() if not drill.diff or drill.diff == 0 then drill.dayGet = {} drill.boxGet = {} drill.myHelpIndex = 0 drill.myHelpHero = nil drill.helpoutList = nil drill.time = now drill.diff, drill.drillId = checkSaoDang(human, diff, drill.lastDiff, drill.lastDrillId) local drillData = DrillDB.getDrillDataByUuid(human.db._id) -- 临时处理 if not drillData then quest(human, drill.drillId) else quest(human, drillData.drillId + 1) end saodangQuest(human, drill.drillId ) queryDrillId(human) end end -- 获取宝箱状态 function getBoxState(drill, index) local state = DRILL_BOX_STATE_0 if not drill.drillId or drill.drillId <= 0 then return state end local config = DrillExcel.box[index] if drill.drillId > config.needDrill then state = DRILL_BOX_STATE_1 end if drill.boxGet and drill.boxGet[index] and drill.boxGet[index].state then state = DRILL_BOX_STATE_2 end return state end -- 查询关卡Id function queryDrillId(human, drillData, openPanel) -- openPanel: 是否打开界面,默认为true(打开界面) -- false-不打开界面,只刷新数据;true-打开界面 if openPanel == nil then openPanel = true -- 默认打开界面 end drillData = drillData or DrillDB.getDrillDataByUuid(human.db._id) if not drillData then -- 没有记录 请求第一关 fixDrillDB(human) return diffChoseQuery(human) -- quest(human) end local drill = human.db.drill if not drill then -- drill 数据不存在,初始化 fixDrillDB(human) drill = human.db.drill if not drill then return diffChoseQuery(human) end end local diff = drill.diff if not drill.diff or drill.diff == 0 then diff = drillData.diff end if diff == 0 then return diffChoseQuery(human) end local msgRet = Msg.gc.GC_DRILL_ID -- 按照协议定义的顺序赋值 -- 1. drillId (byte类型,范围0-255,防止溢出) local drillIdValue = drillData.drillId or 1 if drillIdValue > 255 or drillIdValue < 0 then --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: drillId溢出,原始值="..drillIdValue..",限制后="..math.min(math.max(drillIdValue, 0), 255)) end msgRet.drillId = math.min(math.max(drillIdValue, 0), 255) -- 2. diff (byte类型,范围0-255,防止溢出) local diffValue = diff or 1 if diffValue > 255 or diffValue < 0 then --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: diff溢出,原始值="..diffValue..",限制后="..math.min(math.max(diffValue, 0), 255)) end msgRet.diff = math.min(math.max(diffValue, 0), 255) -- 3. box (数组) - 协议定义最大长度为5 local boxCount = math.min(#DrillExcel.box, 5) msgRet.box[0] = boxCount --秘宝加成 local heroExpMul = getTalismanAdd(human) for k = 1, boxCount do local config = DrillExcel.box[k] local net = msgRet.box[k] -- index 和 needId 都是 byte 类型,防止溢出 if k > 255 or k < 0 then --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: box index溢出,原始值="..k..",限制后="..math.min(math.max(k, 0), 255)) end net.index = math.min(math.max(k, 0), 255) local needIdValue = config.needDrill or 0 if needIdValue > 255 or needIdValue < 0 then --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: box needId溢出,原始值="..needIdValue..",限制后="..math.min(math.max(needIdValue, 0), 255)) end net.needId = math.min(math.max(needIdValue, 0), 255) net.state = getBoxState(drill, k) local itemID1 = config["items"..diff][1][1] local itemCnt1 = config["items"..diff][1][2] if itemID1 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt1 = itemCnt1 + math.ceil(itemCnt1 * heroExpMul) end local itemID2 = config["items"..diff][2][1] local itemCnt2 = config["items"..diff][2][2] if itemID2 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt2 = itemCnt1 + math.ceil(itemCnt2 * heroExpMul) end Grid.makeItem(net.reward[1], itemID1, itemCnt1 ) Grid.makeItem(net.reward[2], itemID2, itemCnt2 ) net.reward[0] = 2 if config["items"..diff][3] then local itemID3 = config["items"..diff][3][1] local itemCnt3 = config["items"..diff][3][2] if itemID3 == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt3 = itemCnt1 + math.ceil(itemCnt3 * heroExpMul) end Grid.makeItem(net.reward[3], itemID3, itemCnt3 ) net.reward[0] = 3 end end -- 4. dayGet (数组) msgRet.dayGet[0] = 2 local dayJinbi = drill.dayGet and drill.dayGet[ItemDefine.ITEM_JINBI_ID] or 0 local dayCoin = drill.dayGet and drill.dayGet[ItemDefine.ITEM_DRILL_COIN_ID] or 0 Grid.makeItem(msgRet.dayGet[1], ItemDefine.ITEM_JINBI_ID, dayJinbi ) Grid.makeItem(msgRet.dayGet[2], ItemDefine.ITEM_DRILL_COIN_ID, dayCoin ) -- 5. maxDiff (byte类型,范围0-255,防止溢出) -- 注意:如果 maxDiff 为 0,应该视为未设置,使用默认值 1(因为 0 在 Lua 中是 truthy) local maxDiffValue = (drill.maxDiff == nil or drill.maxDiff == 0) and 1 or drill.maxDiff if maxDiffValue > 255 or maxDiffValue < 0 then --Log.write(Log.LOGID_DEBUG, "[queryDrillId] WARNING: maxDiff溢出,原始值="..maxDiffValue..",限制后="..math.min(math.max(maxDiffValue, 0), 255)) end msgRet.maxDiff = math.min(math.max(maxDiffValue, 0), 255) -- 6. canOneClickSaodang -- 计算是否开启一键扫荡 local canOneClickSaodang = 0 -- 检查是否购买了基金 local overflowState = human.db.overflow and human.db.overflow.state and human.db.overflow.state[OverflowFundLogic.OVERFLOW_TYPE_2] local hasFund = overflowState ~= nil --Log.write(Log.LOGID_DEBUG, "[queryDrillId] 检查基金状态: overflow="..tostring(human.db.overflow ~= nil)..", state="..tostring(human.db.overflow and human.db.overflow.state ~= nil)..", overflowState[2]="..tostring(overflowState)..", hasFund="..tostring(hasFund)) if hasFund then -- 检查试炼是否开启 local drillOpen = isOpen(human, false) if drillOpen then -- 检查是否有 drill 数据 if drill then -- 检查是否有 drillData 数据 if drillData then -- 检查 diff 不为 0 if diff ~= 0 then -- 已购买基金且满足其他条件,开启一键扫荡(已去掉等级限制和关卡ID限制) -- 注意:即使 drillId=1,也显示按钮,实际扫荡时会检查是否有可扫荡的关卡 canOneClickSaodang = 1 else --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: diff="..diff.." == 0") end else --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: drillData为nil") end else --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: drill为nil") end else --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: 试炼未开启") end else --Log.write(Log.LOGID_DEBUG, "[queryDrillId] canOneClickSaodang=0: 未购买奢华基金(OVERFLOW_TYPE_2)") end msgRet.canOneClickSaodang = canOneClickSaodang -- 7. openPanel msgRet.openPanel = (openPanel == true) and 1 or 0 -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 是否被击杀 function isObjKill(drillObj) if drillObj == nil then return end if drillObj.objStatus == nil then return end for _, hpRate in pairs(drillObj.objStatus) do if hpRate > 0 then return end end return true end -- 查询关卡状态 function query(human, drillId) --if not isOpen(human, true) then return end local drill = human.db.drill if not drill then return end local drillCfg = DrillExcel.drill[drillId] if not drillCfg then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end local drillObj = drillData.drillObjs[drillId] if not drillObj then if drillId < 15 and drillData.drillId == drillId then quest(human, drillId) end return end --秘宝加成 local heroExpMul = getTalismanAdd(human) local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204) local rewardCnt = double and 2 or 1 --require("common.Util").printTable(drillObj) local nowId = drillData.drillId local msgRet = Msg.gc.GC_DRILL_INFO msgRet.drillId = drillId msgRet.svrName = drillObj.svrName or Config.DB_NAME RoleLogic.makeRoleBase(drillObj, msgRet.roleBase) msgRet.reward[0] = 0 msgRet.double = double and 1 or 0 local itemConfig = drillCfg.items if drill.diff == DIFF_ELITE then itemConfig = drillCfg.items2 elseif drill.diff == DIFF_INCUBI then itemConfig = drillCfg.items3 end for _, item in pairs(itemConfig) do msgRet.reward[0] = msgRet.reward[0] + 1 local itemCnt = item[2] * rewardCnt if item[1] == ItemDefine.ITEM_GREEN_EXP_ID then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end Grid.makeItem(msgRet.reward[msgRet.reward[0]], item[1], itemCnt) --Grid.makeItem(msgRet.reward[msgRet.reward[0]], item[1], item[2] * rewardCnt) end msgRet.defence[0] = 0 for i = 1, CombatDefine.COMBAT_HERO_CNT do local obj = drillObj.heroList[i] if obj and i ~= CombatDefine.BACKUP_POS[1] then local hpRate = DrillLogicAttribute.getObjHpRate(drillObj, obj.bagIndex) local hp = math.ceil(INIT_HP_MAX * hpRate) local hpMax = INIT_HP_MAX hp = nowId > drillId and 0 or hp local others = HeroGrid.createOthers(obj.lv, hp, hpMax, obj.star) msgRet.defence[0] = msgRet.defence[0] + 1 if drillObj.monsterOutID and drillObj.monsterOutID > 0 then HeroGrid.makeHeroSimpleByMonsterID(msgRet.defence[msgRet.defence[0]], obj.id, others) else HeroGrid.makeHeroSimpleByID(msgRet.defence[msgRet.defence[0]], obj.id, i, others) end end end local quick = CombatLogic.getQuick(human, CombatDefine.COMBAT_TYPE9) local showNext = 1 -- if getMaxDiff(human) >= drill.diff and human.db.lv >= SAODANG_COND_LEVEL then -- showNext = 1 -- end --取消难度限制 -- if human.db.lv >= SAODANG_COND_LEVEL then -- showNext = 1 -- end msgRet.quick = quick or 0 msgRet.showNext = showNext --Msg.trace(msgRet) Msg.send(msgRet, human.fd) -- 推送英雄的状态信息 sendHeroList(human, drillData.heroStatus) end local FIX_LIST = {} function sendHeroList(human, heroStatus) local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end local drill = human.db.drill if not drill then return end heroStatus = heroStatus and heroStatus or drillData.heroStatus local config = DrillExcel.define[drillData.diff] local msgRet = Msg.gc.GC_DRILL_HERO msgRet.isFirst = 1 msgRet.isLast = 0 msgRet.heroList[0] = 0 msgRet.helpList[0] = 0 local limit = human.drill or {} -- 雇佣英雄 if drillData.helpUuids then for targetUuid, v in pairs(drillData.helpUuids) do msgRet.helpList[0] = msgRet.helpList[0] + 1 local net = msgRet.helpList[msgRet.helpList[0]] if fontHelpNet(net, targetUuid, true) then -- 其它数据 local hpRate = DrillLogicAttribute.getHelpHpRate(drillData, targetUuid) net.heroSimple.hp = math.ceil(INIT_HP_MAX * hpRate) net.heroSimple.hpMax = INIT_HP_MAX if limit.combatHelpUuid and limit.combatHelpUuid == targetUuid then net.pos = human.drill.combatHelpPos end if v.win or net.heroSimple.hp <= 0 then net.state = 1 net.pos = 0 end end end end local heroMinLevel = config and config.heroMinLevel or 0 -- 背包的英雄 for index,heroGrid in pairs(human.db.heroBag) do if index ~= 0 and heroGrid.lv >= heroMinLevel then if msgRet.heroList[0] >= #msgRet.heroList then Msg.send(msgRet, human.fd) msgRet.heroList[0] = 0 msgRet.helpList[0] = 0 msgRet.isFirst = 0 end msgRet.heroList[0] = msgRet.heroList[0] + 1 local heroNet = msgRet.heroList[msgRet.heroList[0]] HeroGrid.makeHeroSimple(heroNet, heroGrid, index) -- 其它数据 local hpRate = DrillLogicAttribute.getHeroHpRate(drillData, heroGrid.uuid) heroNet.hp = math.ceil(INIT_HP_MAX * hpRate) heroNet.hpMax = INIT_HP_MAX end end if msgRet.heroList[0] > 0 or msgRet.isFirst == 1 then msgRet.isLast = 1 -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end end function drillBoxGet(human, index) local drill = human.db.drill if not drill or not drill.diff or drill.diff == 0 then return end local config = DrillExcel.box[index] if not config then return end local state = getBoxState(drill, index) if state ~= 1 then return end drill.boxGet = drill.boxGet or {} drill.boxGet[index] = drill.boxGet[index] or {} drill.boxGet[index].cnt = drill.boxGet[index].cnt or 0 drill.boxGet[index].cnt = drill.boxGet[index].cnt + 1 local msgRet = Msg.gc.GC_DRILL_BOX_GET msgRet.type = 0 msgRet.index = index local random = math.random(1, 100) if random <= 10 and drill.boxGet[index].cnt < DRILL_BOX_GOD_MAX then -- 诸神的怜悯 msgRet.type = drill.boxGet[index].cnt >= DRILL_BOX_GOD_MAX - 1 and 2 or 1 else drill.boxGet[index].state = 1 end Msg.send(msgRet, human.fd) local itemConfig = config.items1 if drill.diff == DIFF_ELITE then itemConfig = config.items2 elseif drill.diff == DIFF_INCUBI then itemConfig = config.items3 end --秘宝加成 local heroExpMul = getTalismanAdd(human) local awardVec = {} for i, v in ipairs(itemConfig) do local itemID = v[1] local itemCnt = v[2] if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end awardVec[i]= {itemID, itemCnt} end --BagLogic.addItemList(human, itemConfig, "drill") BagLogic.addItemList(human, awardVec, "drill") RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201) -- queryDrillId(human) end --奖励预览 function rewardPreview(human) if not isOpen(human, true) then return end local msgRet = Msg.gc.GC_DRILL_REWARD_PREVIEW msgRet.list[0] = 0 --秘宝加成 local heroExpMul = getTalismanAdd(human) for drillId, cf in pairs(DrillExcel.drill) do msgRet.list[0] = msgRet.list[0] + 1 local net = msgRet.list[msgRet.list[0]] net.drillId = drillId net.items[0] = #cf.items for i, item in ipairs(cf.items) do local itemID = item[1] local itemCnt = item[2] if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end Grid.makeItem(net.items[i], itemID, itemCnt) end end Msg.send(msgRet, human.fd) end -- 邮件提醒 function sendDrillTip(human) if human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] == nil then human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] = os.time() end local curTime = os.time() local daySec = 3600 * 24; if curTime - human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] < daySec then return end human.db.mailtips[RoleSystemLogic.ROLE_MAILTIPS_ID1] = curTime if not isOpen(human) then return end end -------------------------------------------------------------------------------------- --加入跨服试炼队列 --检测是否有竞技场阵容 --加入数据推送至中心服 [g->m] function onJjcPos(human) local heroList, helpList, rolebase , formation, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE3) if not heroList or not next(heroList) then return end -- 没有上阵 local drillObj = DrillDB.createDrillObj(human) if not drillObj then return end DrillDB.updateDrillObj(drillObj) end --请求关卡记录 ------------ 匹配规则 ----------------------- function getDifficulty(quJian, diff,config) local str1 = "" local str2 = "" local stradd = "" if quJian == 2 then stradd = "1" end if diff == DIFF_NORMAL then str1 = "zdlMin" str2 = "zdlMax" elseif diff == DIFF_ELITE then str1 = "zdlMinElite" str2 = "zdlMaxElite" elseif diff == DIFF_INCUBI then str1 = "zdlMinIncubi" str2 = "zdlMaxIncubi" end if stradd == "" then return config[str1], config[str2] else return config[str1..stradd], config[str2..stradd] end end function getZhanLiByNpc(zhandouli) local DrillNpcExcel = DrillExcel.npc local maxCnt = #DrillNpcExcel if DrillNpcExcel[maxCnt].zhandouli[2] < zhandouli then return DrillNpcExcel[maxCnt].zhandouli[1], DrillNpcExcel[maxCnt].zhandouli[2] end for k, config in ipairs(DrillExcel.npc) do if config.zhandouli[1] <= zhandouli and config.zhandouli[2] >= zhandouli then return config.zhandouli[1], config.zhandouli[2] end end return DrillExcel.npc[1].zhandouli[1], DrillExcel.npc[1].zhandouli[2] end function findRandomObj(zdlMin, zdlMax, notTab, isRobot) local drillObj = DrillDB.randomDrillObj(zdlMin, zdlMax, notTab, isRobot) return drillObj end -- 请求关卡 function pipei(human, drillId, diff, zhandouli, notTab) local drillCfg = DrillExcel.drill[drillId] if not drillCfg then return end local minPer, maxPer = getDifficulty(1, diff, drillCfg) local zdlMin = math.ceil(minPer / 10000 * zhandouli) local zdlMax = math.ceil(maxPer / 10000 * zhandouli) local drillObj if (diff == DIFF_NORMAL and drillId <= 10) or (diff == DIFF_ELITE and drillId <= 8) or (diff == DIFF_INCUBI and drillId <= 6) then drillObj = findRandomObj(zdlMin, zdlMax, notTab, true) if not drillObj then minPer, maxPer = getDifficulty(2, diff, drillCfg) zdlMin = math.ceil(minPer / 10000 * zhandouli) zdlMax = math.ceil(maxPer / 10000 * zhandouli) if zdlMin <= DrillExcel.npc[1].zhandouli[2] then zdlMin = DrillExcel.npc[1].zhandouli[1] zdlMax = DrillExcel.npc[1].zhandouli[2] end drillObj = findRandomObj(zdlMin, zdlMax, notTab, true) if not drillObj then zdlMin,zdlMax = getZhanLiByNpc(zhandouli) drillObj = findRandomObj(zdlMin, zdlMax, notTab, true) end end else drillObj = findRandomObj(zdlMin, zdlMax, notTab) if not drillObj then minPer, maxPer = getDifficulty(2, diff, drillCfg) zdlMin = math.ceil(minPer / 10000 * zhandouli) zdlMax = math.ceil(maxPer / 10000 * zhandouli) drillObj = findRandomObj(zdlMin, zdlMax, notTab) if not drillObj then minPer = minPer - 500 maxPer = maxPer + 500 zdlMin = math.ceil(minPer / 10000 * zhandouli) zdlMax = math.ceil(maxPer / 10000 * zhandouli) drillObj = findRandomObj(zdlMin, zdlMax, notTab) if not drillObj then if zdlMin <= DrillExcel.npc[1].zhandouli[2] then zdlMin = DrillExcel.npc[1].zhandouli[1] zdlMax = DrillExcel.npc[1].zhandouli[2] end drillObj = findRandomObj(zdlMin, zdlMax, notTab, true) if not drillObj then zdlMin = zhandouli - 50001 zdlMax = zhandouli + 50001 zdlMin = zdlMin > DrillExcel.npc[1].zhandouli[1] and zdlMin or DrillExcel.npc[1].zhandouli[1] zdlMax = zdlMax > DrillExcel.npc[1].zhandouli[2] and zdlMax or DrillExcel.npc[1].zhandouli[2] local maxID = #DrillExcel.npc zdlMin = zdlMin < DrillExcel.npc[maxID].zhandouli[1] and zdlMin or DrillExcel.npc[maxID].zhandouli[1] zdlMax = zdlMax < DrillExcel.npc[maxID].zhandouli[2] and zdlMax or DrillExcel.npc[maxID].zhandouli[2] drillObj = findRandomObj(zdlMin, zdlMax, notTab, true) end end end end end if not drillObj then return Broadcast.sendErr(human, Lang.DRILL_NOT_FING_DRILL) end return drillObj end ----------------------------------------------------------- --计算战力区间 function fristQust(human, drillId) local drill = human.db.drill if not drill then return end local diff = drill.diff local dirllDefConfig = DrillExcel.define[drill.diff] if not dirllDefConfig then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if drillData then return end drillId = drillId and drillId or 1 if drillId > dirllDefConfig.maxDrillID then return end local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1) if zhandouli <= 0 then drill.diff = 0 return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT) end local notTab = {} if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手 zhandouli = human.maxZDL.zhandouli end local drillObj = pipei(human, drillId, diff, zhandouli, notTab) if not drillObj then return end local drillData = DrillDB.createDrillData(human, drillId) drillData.diff = diff drillData.drillObjs[drillId] = Util.copyTable(drillObj) DrillDB.updateDrillData(drillData) queryDrillId(human, drillData) end function quest(human, drillId) local drill = human.db.drill if not drill then return end local diff = drill.diff local dirllDefConfig = DrillExcel.define[drill.diff] if not dirllDefConfig then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then fristQust(human, drillId) return end if drillId > dirllDefConfig.maxDrillID then return end local notTab = {} notTab[#notTab + 1] = human.db._id if drillData then for i = 1, dirllDefConfig.maxDrillID do local drillObj = drillData.drillObjs[i] if drillObj then notTab[#notTab + 1] = drillObj._id or drillObj.uuid end end end local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1) if zhandouli <= 0 then return Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT) end if human.maxZDL and human.maxZDL.zhandouli and human.maxZDL.zhandouli > zhandouli then -- 获取玩家真正的最高战力 防止玩家 战役上阵 战力低 去匹配 低战力对手 zhandouli = human.maxZDL.zhandouli end local drillObj = pipei(human, drillId, diff, zhandouli, notTab) drillData.drillObjs[drillId] = Util.copyTable(drillObj) DrillDB.updateDrillData(drillData) -- queryDrillId(human, drillData) end -- myHelpIndex = 1, -- 我选择的援助出去英雄 -- helpoutList = {}, -- 我选择的援助英雄 -- 选择自己的 出战 英雄 function dispatchMyHelpHero(human, index) local drill = human.db.drill if not drill then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end -- if drillData.helpInfo then -- return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_HAD) -- end -- 当日已经派遣过 if drill.myHelpIndex and drill.myHelpIndex > 0 then return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_HAD) end local heroGrid = human.db.heroBag[index] if type(heroGrid) ~= "table" then return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_INDEX) end local combatObj = CombatLogic.createHumanObj(human, heroGrid.uuid) local rolebase = CombatLogic.createRoleBaseByDB(human.db) if not combatObj or not rolebase then return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_MY_ERR_INDEX) end combatObj.bagIndex = nil combatObj.friendUuid = human.db._id local helpInfo = {} helpInfo.heroGrid = heroGrid helpInfo.combatObj = combatObj helpInfo.rolebase = rolebase drillData.helpInfo = helpInfo drill.myHelpIndex = index DrillDB.updateDrillData(drillData) local heroID = heroGrid.id local heroConfig = HeroExcel.hero[heroID] if heroConfig == nil then return end drill.myHelpIndex = index drill.myHelpHero = helpInfo helpHeroFriendQuery(human) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201) end -- 获取最大血量 function getCombatObjHpMax(obj) if obj.hpMax then return obj.hpMax end local hpMax = obj.attrs[RoleDefine.HP] hpMax = math.ceil(hpMax * (1 + obj.attrs[RoleDefine.HP_RATE]/10000)) return hpMax end -- 封装助战结构体 function fontHelpNet(net, targetUuid) local tDrillData = DrillDB.getDrillDataByUuid(targetUuid) if not tDrillData then return end local tHelpInfo = tDrillData.helpInfo if not tHelpInfo then return end net.uuid = targetUuid net.name = tHelpInfo.rolebase.name net.state = 0 net.pos = 0 HeroGrid.makeHeroSimple(net.heroSimple, tHelpInfo.heroGrid) return true end local helpHeroFields = {lv = 1, name = 1, head = 1, technology=1, heroBag = 1, combatHero = 1, drill = 1} function helpHeroFriendQuery(human) local drill = human.db.drill if not drill then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end local now = os.time() local msgRet = Msg.gc.GC_DRILL_FRIEND_HELP_QUERY msgRet.myHelpIndex = drill.myHelpIndex and drill.myHelpIndex or 0 msgRet.ownChose[0] = 0 msgRet.herolist[0] = 0 local len = 0 -- 我已经选择了 部分 援助英雄 if drill.helpoutList then for uuid, v in pairs(drill.helpoutList) do local net = msgRet.ownChose[msgRet.ownChose[0] + 1] if fontHelpNet(net, uuid, true) then msgRet.ownChose[0] = msgRet.ownChose[0] + 1 end end end -- 玩家最多选择 三位好友援助英雄 if len < 3 then len = 0 local cnt, list = FriendDBLogic.getFriendUuids(human.db._id) for i = 1, cnt do local targetUuid = list[i].uuid if not drill.helpoutList or not drill.helpoutList[targetUuid] then if msgRet.herolist[0] >= #msgRet.herolist then break end local net = msgRet.herolist[msgRet.herolist[0] + 1] if fontHelpNet(net, targetUuid) then msgRet.herolist[0] = msgRet.herolist[0] + 1 end end end end -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 选择支援我的好友助战 local HELP_MAIL_ITEMS = {{}} function choseHelpFriendHero(human, uuid) if not uuid or uuid == "" then return end local drill = human.db.drill if not drill then return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end -- 今天 已经选择该玩家英雄援助了 if drill.helpoutList and drill.helpoutList[uuid] then return end if not FriendDBLogic.isFriend(human.db._id, uuid) then return end if drill.helpoutList then local len = 0 for k, _ in pairs(drill.helpoutList) do len = len + 1 end if len >= 3 then return end end local friendHuman friendHuman = ObjHuman.onlineUuid[uuid] if not friendHuman then local db = RoleDBLogic.getDb(uuid, helpHeroFields) if db then friendHuman = {db = db} end end local drillFriend = friendHuman.db.drill if not drillFriend or not drillFriend.myHelpHero then return end -- 检查这个数据是否是当天设置的 if not Util.isSameDay(drillFriend.time) then return end local tDrillData = DrillDB.getDrillDataByUuid(uuid) local helpInfo = tDrillData and tDrillData.helpInfo if not helpInfo then return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_FRIEND_ERR_INFO) end local maxZhandouli = HeroLogic.getHeroMaxZDL(human) if helpInfo.heroGrid.zhandouli > maxZhandouli * MAX_HEROCOMBAT_MUL / 100 then return Broadcast.sendErr(human, Util.format(Lang.LIANYU_MY_SELECT_ERR_ZDL, MAX_HEROCOMBAT_MUL)) end drill.helpoutList = drill.helpoutList or {} drill.helpoutList[uuid] = {} drill.helpoutList[uuid].time = os.time() DrillLogicAttribute.setHelp(drillData ,uuid) DrillDB.updateDrillData(drillData) -- 给好友发送雇佣奖励 HELP_MAIL_ITEMS[1][1] = ItemDefine.ITEM_FRIEND_ID HELP_MAIL_ITEMS[1][2] = FRIEND_ITEM_CNT local mailConfig = MailExcel.mail[MailDefine.MAIL_ID_DRILL_HELP] local title = mailConfig.title local senderName = mailConfig.senderName local content = Util.format(mailConfig.content, human.db.name) MailManager.add(MailManager.SYSTEM, uuid, title, content, HELP_MAIL_ITEMS, senderName) helpHeroFriendQuery(human) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201) end function curFuhuoCnt(human, drillData) local maxCnt = VipLogic.getPowerArgs(human, VipLogic.VIP_POWER5) local oldCnt = DrillLogicAttribute.getOperCnt(drillData, DrillLogicAttribute.DRILL_OPER_1) local curCnt = maxCnt - oldCnt curCnt = curCnt > 0 and curCnt or 0 return maxCnt, curCnt end function getResetNeedZuanshi(drillData, maxCnt) local oldCnt = DrillLogicAttribute.getOperCnt(drillData, DrillLogicAttribute.DRILL_OPER_1) if oldCnt >= maxCnt then return 0 end local operConfig = DrillExcel.oper[oldCnt + 1] return operConfig.zuanshi end function fuhuoQuery(human) local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end local msgRet = Msg.gc.GC_DRILL_FUHUO_QUERY msgRet.maxCnt, msgRet.canCnt = curFuhuoCnt(human, drillData) msgRet.needZuanshi = getResetNeedZuanshi(drillData, msgRet.maxCnt) Msg.send(msgRet, human.fd) end function getHelpHeroState(human, args) local choseUuid = args[1] local drill = human.db.drill if not drill then return false end if drill.helpoutList and drill.helpoutList[choseUuid] then local hero = drill.helpoutList[choseUuid] -- 挑战胜利过的 不能作为出战英雄 if hero.winCnt and hero.winCnt > 0 then return false end local hp = hero.helpObj.attrs[RoleDefine.HP] if hp <= 0 then return false end return true, hero.heroObj end return false end -- 助战英雄上阵 function setHelpCombatPos(human, uuid, pos) if not isOpen(human, true) then return end local drill = human.db.drill if not drill then return false end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return end if drill.helpoutList and drill.helpoutList[uuid] then human.drill = human.drill or {} human.drill.combatHelpUuid = uuid human.drill.combatHelpPos = pos end end -- 防御方数据 function getDefender(drillObj) local objList = {} for index, obj in pairs(drillObj.heroList) do if DrillLogicAttribute.getObjHpRate(drillObj, obj.bagIndex) > 0 and index ~= CombatDefine.BACKUP_POS[1] then -- 剔除死亡的 objList[index] = obj end end local roleBase = {} RoleLogic.makeRoleBase(drillObj, roleBase) return objList, drillObj.helpList, roleBase, drillObj.formation, drillObj.jiban, drillObj.elfList end -- 攻击方数据 function getAttacker(human, drillData, pos2uuidAtk) local drill = human.db.drill if not drill then return end local objList, helpList, rolebase, formation, jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE9) for pos, obj in pairs(objList) do local heroGrid = human.db.heroBag[obj.bagIndex] if heroGrid then pos2uuidAtk[pos] = heroGrid.uuid end end -- 助战英雄 local combatHelpUuid = human.drill and human.drill.combatHelpUuid local combatHelpPos = human.drill and human.drill.combatHelpPos if combatHelpUuid and combatHelpPos then if drill.helpoutList and drill.helpoutList[combatHelpUuid] then local tDrillData = DrillDB.getDrillDataByUuid(combatHelpUuid) local combatHelp = tDrillData and tDrillData.helpInfo if combatHelp and DrillLogicAttribute.getHelpHpRate(drillData, combatHelpUuid) > 0 and CombatPosLogic.checkPos(formation, combatHelpPos) then objList[combatHelpPos] = combatHelp.combatObj pos2uuidAtk[combatHelpPos] = combatHelpUuid end end end return objList, helpList, rolebase, formation, jiban, elfList end -------------------------------------- combat ----------------------------------------- -- 判断是否合适上阵 local function isFixCombatPos(heroGrid, drillData, config) if type(heroGrid) ~= "table" then return end if not drillData then return end if config and config.heroMinLevel and heroGrid.lv < config.heroMinLevel then return end -- 等级不满足 local hpRate = DrillLogicAttribute.getHeroHpRate(drillData, heroGrid.uuid) if hpRate <= 0 then return end -- 死掉了 return true end -- 不合适的下阵 function updateCombatPosCheck(human, drillData) local combatHero = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE9) if not combatHero then return end local drillDB = human.db.drill local config = DrillExcel.define[drillData.diff] for pos, uuid in pairs(combatHero) do local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid) if heroGrid and not isFixCombatPos(heroGrid, drillData, config) then combatHero[pos] = nil end end end -- 战斗前加属性 function onFightBegin(human, cbParam) for index = 1, CombatDefine.COMBAT_HERO_ALL_CNT do local obj = CombatImpl.objList[index] if obj then if index <= CombatDefine.COMBAT_HERO_CNT then calcAttrAtk(human, index, obj,cbParam ) else calcAttrDef(human, index, obj, cbParam) end end end end function getHelpGrid(human, uuid) local drill = human.db.drill if drill.helpoutList and drill.helpoutList[uuid] then return drill.helpoutList[uuid].heroGrid end end -- 所有属性计算完毕,重新设置血量(攻击) function calcAttrAtk(human, pos, obj, cbParam) local uuid = cbParam.pos2uuidAtk[pos] if not uuid then return end local hpRate = nil if (obj.bagIndex or 0) > 0 then hpRate = DrillLogicAttribute.getHeroHpRate(cbParam.drillData, uuid) else hpRate = DrillLogicAttribute.getHelpHpRate(cbParam.drillData, uuid) end local hpMax = CombatObj.getHpMax(obj) obj.hp = math.ceil(hpRate * hpMax) end -- 所有属性计算完毕,重新设置血量(防守) function calcAttrDef(human, pos, obj, cbParam) local hpRate = DrillLogicAttribute.getObjHpRate(cbParam.drillObj, obj.bagIndex) local hpMax = CombatObj.getHpMax(obj) obj.hp = math.ceil(hpRate * hpMax) end -- 战斗 function fight(human, args) if not isOpen(human, true) then return end if human.db.combatQuick and human.db.combatQuick[CombatDefine.COMBAT_TYPE9] and human.db.combatQuick[CombatDefine.COMBAT_TYPE9] == 1 then local combatHero = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE9 ) if CombatLogic.isCombatHeroEmpty(combatHero) then queryDrillId(human) return Broadcast.sendErr(human, Lang.DRILL_NOT_FIGHT_NOT_HERO) end end local drill = human.db.drill if not drill then return false end local drillDB = human.db.drill local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return Broadcast.sendErr(human, Lang.DRILL_IS_FINSH) end local drillId = tonumber(args[1] or 0) if drillId ~= drillData.drillId then return end local config = DrillExcel.drill[drillId] if not config then return end local drillObj = drillData.drillObjs[drillId] if not drillObj then return end -- 不存在。。 updateCombatPosCheck(human, drillData) local args = {} local pos2uuidAtk = {} args.defender, args.defHelp, args.defRBase, args.defFormation, args.defJiban, args.defElfList = getDefender(drillObj) args.attacker, args.atkHelp, args.atkRBase, args.atkFormation, args.atkJiban, args.atkElfList = getAttacker(human, drillData, pos2uuidAtk) args.drillId = drillData.drillId local cbParam = {} cbParam.pos2uuidAtk = pos2uuidAtk cbParam.diff = drillData.diff cbParam.drillId = drillData.drillId cbParam.drillData = drillData cbParam.drillObj = drillObj cbParam.combatHelpPos = human.drill and human.drill.combatHelpPos cbParam.combatHelpUuid = human.drill and human.drill.combatHelpUuid CombatLogic.combatBegin(human, config.mapID, args, CombatDefine.COMBAT_TYPE9, cbParam) end -- 获取当前地图ID function getMapID(human, args) local drillDB = human.db.drill local drillData = DrillDB.getDrillDataByUuid(human.db._id) local drillId = tonumber(args[1] or args.drillId or 0) if drillId ~= drillData.drillId then return end local config = DrillExcel.drill[drillId] if not config then return end return config.mapID end -- 刷新drillData记录的血量 function combatOnUpdate(human, cbParam, combatInfo) for index = 1, CombatDefine.COMBAT_HERO_CNT do -- 更新攻击方血量 local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index) local atkObj = combatInfo.objList[atkPos] if atkObj ~= nil then local hp = atkObj.hp local hpMax = CombatObj.getHpMax(atkObj) local hpRate = hp / hpMax local uuid = cbParam.pos2uuidAtk[index] if (atkObj.bagIndex or 0) > 0 then DrillLogicAttribute.setHeroHpRate(cbParam.drillData, uuid, hpRate) else DrillLogicAttribute.setHelpHpRate(cbParam.drillData, uuid, hpRate) end end -- 更新防守方血量 local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, index) local defObj = combatInfo.objList[defPos] if defObj ~= nil then local hp = defObj.hp local hpMax = CombatObj.getHpMax(defObj) local hpRate = hp / hpMax DrillLogicAttribute.setObjHpRate(cbParam.drillObj, defObj.bagIndex, hpRate) end end updateCombatPosCheck(human, cbParam.drillData) end -- 战胜回调 function onFightWinCallback(human, result , diff,drillID) LiLianLogic.onCallback(human,LiLianLogic.LILIAN_OUTID11,1,diff) DailyTaskLogic.recordDailyTaskFinishCnt(human, DailyTaskLogic.DAILY_TASK_ID_11, 1) HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE16, 1) MengxinLogic.onCallBack(human,MengxinLogic.MX_TASK_TYPE_8,drillID) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1201) end -- 援助英雄 添加胜利 function addHelpWin(human, drillData) if human.drill and human.drill.combatHelpUuid then DrillLogicAttribute.setHelpWin(drillData, human.drill.combatHelpUuid) end end -- 通关回调 function tongGuan(human, diff) if getMaxDiff(human) < diff then setMaxDiff(human, diff) end end -- 战斗结束 function onFightEnd(human, result, combatType, cbParam, combatInfo) local isOtherDay = false if not Util.isSameDay(combatInfo.time) then isOtherDay = true end local drillDB = human.db.drill if not drillDB then return end combatOnUpdate(human, cbParam, combatInfo) local drillData = cbParam.drillData local isKill = true if not isObjKill(cbParam.drillObj) then -- 未击杀对面 isKill = false end local diff = cbParam.diff or drillData.diff if not isOtherDay then if not isKill then return DrillDB.updateDrillData(drillData) end -- 刷新最大通关难度 local dirllDefConfig = DrillExcel.define[diff] if cbParam.drillId >= dirllDefConfig.maxDrillID then tongGuan(human, diff) ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_17,1) HeroLogLogic.finishTaskCB(human,HeroLogLogic.HERO_LOG_TYPE_5,1) end drillData.drillId = drillData.drillId + 1 drillDB.drillId = drillData.drillId addHelpWin(human, drillData) DrillDB.updateDrillData(drillData) -- 手动通关后清除扫荡完成标记,允许再次扫荡 if drillDB then drillDB.oneClickSaodangDone = nil end quest(human, cbParam.drillId + 1) --[[if drillDB.drillId == cbParam.drillId and drillDB.diff == diff then if cbParam.drillId <= dirllDefConfig.maxDrillID then drillDB.drillId = drillDB.drillId + 1 drillData.drillId = drillData.drillId + 1 end addHelpWin(human, drillData) DrillDB.updateDrillData(drillData) quest(human, cbParam.drillId + 1) end]] else if not isKill then updateDaily(human) return end end local drillItems = getDrillItems(cbParam.drillId, diff) local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204) local rewardCnt = double and 2 or 1 combatInfo.double = double and 2 or 0 --秘宝加成 local heroExpMul = getTalismanAdd(human) -- 关卡奖励 local itemList = {} for k, item in ipairs(drillItems) do local itemID = item[1] local itemCnt = item[2] * rewardCnt if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end itemList[k] = {} itemList[k][1] = itemID itemList[k][2] = itemCnt -- itemList[k][4] = sourceId BagLogic.addItem(human, itemID, itemCnt, "drill") if not isOtherDay then drillDB.dayGet = drillDB.dayGet or {} drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt end end combatInfo.rewardItem = itemList human.drill = nil if isOtherDay then updateDaily(human) end -- 回调 onFightWinCallback(human,result, diff,cbParam.drillId) YunYingLogic.onCallBack(human, "onDrill",1) --周任务 -8 WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1) TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1) end --[[ -- 增加关卡 function questMid(fd, msg) local uuid = msg.uuid local drillId = msg.drillId local drillObj = msg.drillObj if not RoleDBLogic.isUuidExistInDB(uuid) then return end local drillData = DrillDB.getDrillDataByUuid(uuid) if not drillData then -- if drillId ~= 1 then return end -- 注意哦 drillData = DrillDB.createDrillData(uuid) else if drillData.drillId ~= drillId then return end end print("drillObj",drillObj._id, drillId) drillData.drillObjs[drillId] = Util.copyTable(drillObj) DrillDB.updateDrillData(drillData) local human = ObjHuman.onlineUuid[uuid] if human == nil then return end queryDrillId(human, drillData) end ]] function isDot(human) local isOpen = RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1204) if not isOpen then return false end if not human.db.drill then return true end for k, _ in ipairs(DrillExcel.box) do if getBoxState(human.db.drill, k) == DRILL_BOX_STATE_1 then return true end end if human.db.drill.myHelpIndex and human.db.drill.myHelpIndex > 0 then return false end return true end function getQuick(human) if getMaxDiff(human) > 0 then return 1 end return 0 end -- 通关消耗钻石来通关当前关卡 function ChallengeLevelByDiamond(human, levelId) local drill = human.db.drill if not drill then return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED) end local drillDB = human.db.drill local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then return Broadcast.sendErr(human, Lang.DRILL_IS_FINSH) end if levelId ~= drillData.drillId then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end local config = DrillExcel.drill[levelId] if not config then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local drillObj = drillData.drillObjs[levelId] if not drillObj then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end if BagLogic.getItemCnt(human, ItemDefine.ITEM_ZUANSHI_ID) < CHALLENGE_DIAMONS then return Broadcast.sendErr(human, Lang.COMMON_NO_ZUANSHI) end BagLogic.delItem(human, ItemDefine.ITEM_ZUANSHI_ID, CHALLENGE_DIAMONS, "drill") local oldDrillID = drillData.drillId local isOtherDay = false local diff = drillData.diff local dirllDefConfig = DrillExcel.define[diff] if drillData.drillId >= dirllDefConfig.maxDrillID then tongGuan(human, diff) ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_17,1) HeroLogLogic.finishTaskCB(human,HeroLogLogic.HERO_LOG_TYPE_5,1) end drillData.drillId = drillData.drillId + 1 drillDB.drillId = drillData.drillId -- addHelpWin(human, drillData) DrillDB.updateDrillData(drillData) -- 手动通关后清除扫荡完成标记,允许再次扫荡 if drillDB then drillDB.oneClickSaodangDone = nil end quest(human, oldDrillID + 1) local drillItems = getDrillItems(oldDrillID, diff) local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204) local rewardCnt = double and 2 or 1 --秘宝加成 local heroExpMul = getTalismanAdd(human) -- 关卡奖励 local itemArray = {} for k, item in ipairs(drillItems) do local itemID = item[1] local itemCnt = item[2] * rewardCnt if itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpMul > 0 then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end itemArray[k] = {itemID, itemCnt} -- BagLogic.addItem(human, itemID, itemCnt, "drill") if not isOtherDay then drillDB.dayGet = drillDB.dayGet or {} drillDB.dayGet[itemID] = (drillDB.dayGet[itemID] or 0) + itemCnt end end -- 回调 onFightWinCallback(human,result, diff, oldDrillID) YunYingLogic.onCallBack(human, "onDrill",1) --周任务 -8 WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1) TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1) -- 更新数据 queryDrillId(human) -- 发放奖励 BagLogic.addItemList(human, itemArray, "drill") end -- 一键扫荡 function oneClickSaodang(human) -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 收到一键扫荡请求") -- 检查是否购买了基金(购买项207) if not human.db.overflow or not human.db.overflow.state or not human.db.overflow.state[OverflowFundLogic.OVERFLOW_TYPE_2] then --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 未购买奢华基金(OVERFLOW_TYPE_2)") return end -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已购买基金,继续执行") -- 检查是否开启了试炼 if not isOpen(human, true) then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 试炼未开启") return end -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 试炼已开启,继续执行") local drill = human.db.drill if not drill then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] drill为nil") return end local drillData = DrillDB.getDrillDataByUuid(human.db._id) if not drillData then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] drillData为nil") return end local diff = drill.diff if not drill.diff or drill.diff == 0 then diff = drillData.diff end if diff == 0 then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] diff="..diff..",需要!=0") return end ---- 获取当前关卡ID local currentDrillId = drillData.drillId or 1 -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 当前关卡ID="..currentDrillId..", diff="..diff) -- 获取总关卡数 local dirllDefConfig = DrillExcel.define[diff] if not dirllDefConfig then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 难度配置不存在,diff="..diff) return end local maxDrillID = dirllDefConfig.maxDrillID -- 如果已经通关所有关卡(drillId > maxDrillID),不允许再次扫荡 if currentDrillId > maxDrillID then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已通关所有关卡,不允许再次扫荡,currentDrillId="..currentDrillId..", maxDrillID="..maxDrillID) Broadcast.sendErr(human, "已通关所有关卡,无法再次扫荡") return end -- 计算可扫荡的关卡数 -- 一键扫荡应该扫荡所有关卡(1到maxDrillID),无论当前关卡ID是多少 local maxSaodangId = maxDrillID -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 一键扫荡:扫荡所有关卡,maxSaodangId="..maxSaodangId..", maxDrillID="..maxDrillID) if maxSaodangId < 1 then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 无可扫荡关卡,maxSaodangId="..maxSaodangId.." < 1") return end -- 计算扫荡后的关卡ID -- 一键扫荡后应该全部通关(newDrillId = maxDrillID + 1) local newDrillId = maxDrillID + 1 -- 16表示已通关所有关卡 -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 计算扫荡后关卡ID: 一键扫荡后全部通关, newDrillId="..newDrillId) -- 检查是否已经扫荡过: -- 由于 newDrillId 总是等于 maxDrillID + 1(全部通关),所以: -- - 如果 currentDrillId <= maxDrillID,那么 newDrillId > currentDrillId,这是正常的,允许扫荡 -- - 如果 currentDrillId > maxDrillID,说明已经全部通关了,不允许再次扫荡(这个检查已经在前面做了) -- 理论上 newDrillId 不会小于或等于 currentDrillId(除非已经全部通关),但为了安全起见,保留检查 if newDrillId < currentDrillId then -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已扫荡过,不允许再次扫荡: currentDrillId="..currentDrillId..", newDrillId="..newDrillId..", maxSaodangId="..maxSaodangId) Broadcast.sendErr(human, "已扫荡过,无法再次扫荡") return end -- 如果 newDrillId == currentDrillId,理论上不会出现(因为 newDrillId 总是 maxDrillID + 1) -- 但为了安全起见,保留检查(通过标记判断是否已经扫荡过) if newDrillId == currentDrillId then if drill.oneClickSaodangDone then --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 已扫荡过(通过标记判断),不允许再次扫荡: currentDrillId="..currentDrillId..", newDrillId="..newDrillId..", maxSaodangId="..maxSaodangId) Broadcast.sendErr(human, "已扫荡过,无法再次扫荡") return end end -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 可扫荡关卡数: maxSaodangId="..maxSaodangId..", 总关卡数="..maxDrillID) -- 双倍奖励 local double = RoleSystemLogic.isDouble(human, RoleSystemDefine.ROLE_SYS_ID_1204) local rewardCnt = double and 2 or 1 -- 秘宝加成 local heroExpMul = getTalismanAdd(human) -- 初始化今日奖励 drill.dayGet = drill.dayGet or {} -- 收集所有奖励到列表中 local itemList = {} -- 遍历所有可扫荡的关卡,收集奖励 for i = currentDrillId, maxSaodangId do local drillItems = getDrillItems(i, diff) if drillItems then for _, item in ipairs(drillItems) do local itemID = item[1] local itemCnt = item[2] * rewardCnt if itemID == ItemDefine.ITEM_GREEN_EXP_ID then itemCnt = itemCnt + math.ceil(itemCnt * heroExpMul) end -- 累加奖励到列表 itemList[itemID] = (itemList[itemID] or 0) + itemCnt drill.dayGet[itemID] = (drill.dayGet[itemID] or 0) + itemCnt end end end -- 使用 addItemList 添加奖励,会自动显示奖励弹窗 if next(itemList) then BagLogic.addItemList(human, itemList, "drill") end -- 发送奖励消息 local msgRet = Msg.gc.GC_DRILL_ONE_CLICK_SAODANG msgRet.drillId = maxSaodangId msgRet.double = double and 1 or 0 local len = 0 local itemInfo = "" for k, v in pairs(drill.dayGet) do len = len + 1 Grid.makeItem(msgRet.itemList[len], k, v) if len > 1 then itemInfo = itemInfo .. ", " end itemInfo = itemInfo .. "itemID="..k..", count="..v end msgRet.itemList[0] = len -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 发送协议数据: drillId="..msgRet.drillId..", double="..msgRet.double..", itemCount="..len..", items=["..itemInfo.."]") Msg.send(msgRet, human.fd) -- 更新关卡ID(已经在发放奖励前检查过了,这里直接更新) local oldDrillId = drillData.drillId drillData.drillId = newDrillId drill.drillId = newDrillId DrillDB.updateDrillData(drillData) -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 更新关卡ID: "..currentDrillId.." -> "..newDrillId.." (drillData.drillId: "..(oldDrillId or "nil").." -> "..newDrillId..")") -- 检查是否全部通关 if newDrillId > maxDrillID then --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 扫荡后已全部通关: newDrillId="..newDrillId.." > maxDrillID="..maxDrillID) else --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 扫荡后未全部通关: newDrillId="..newDrillId.." <= maxDrillID="..maxDrillID..", 可以手动挑战") end -- 设置扫荡完成标记(用于防止重复扫荡) drill.oneClickSaodangDone = true -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 设置扫荡完成标记: oneClickSaodangDone=true") -- 如果通关所有关卡,触发通关回调 if newDrillId > maxDrillID then --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 触发通关回调: newDrillId="..newDrillId.." > maxDrillID="..maxDrillID) tongGuan(human, diff) ChengjiuLogic.onCallback(human, ChengjiuDefine.CJ_TASK_TYPE_17, 1) HeroLogLogic.finishTaskCB(human, HeroLogLogic.HERO_LOG_TYPE_5, 1) --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 通关回调执行完成") else --Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 未触发通关回调: newDrillId="..newDrillId.." <= maxDrillID="..maxDrillID) end -- 更新数据 queryDrillId(human) -- 触发相关回调 YunYingLogic.onCallBack(human, "onDrill", maxSaodangId) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1204) -- 更新任务进度(扫荡了maxSaodangId个关卡,每个关卡胜利一次) for i = 1, maxSaodangId do LiLianLogic.onCallback(human, LiLianLogic.LILIAN_OUTID11, 1, diff) DailyTaskLogic.recordDailyTaskFinishCnt(human, DailyTaskLogic.DAILY_TASK_ID_11, 1) HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE16, 1) MengxinLogic.onCallBack(human, MengxinLogic.MX_TASK_TYPE_8, i) WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_8, 1) -- 触发勇者试炼击杀守卫事件(用于主线任务) TriggerLogic.PublishEvent(TriggerDefine.DRILL_KILL_SHOUWEI, human.db._id, 1) end -- Log.write(Log.LOGID_DEBUG, "[oneClickSaodang] 任务进度已更新: 扫荡关卡数="..maxSaodangId) end