-------------------------------------------------------------- -- 荣耀峡谷(龙族战场) -- 因为活动以服为单位,建议合服时候直接清空活动数据 -- 休战->报名->匹配->侦查->战斗->休战 -- 规则说明 notice.xlsx-helpMisc-85 -- common db -- db.state 当前阶段 -- db.startTime 阶段开始时间戳 -- db.endTime 阶段结束时间戳 -- db.round 战斗阶段轮次 -- db.roundState 战斗阶段轮次状态 -- db.signList [本服]报名列表 [uuid]={roadIndex,zhandouli} -- db.roadList [本服]各路入驻情况 [roadIndex]={[index]=uuid} -- db.roadListSend [本服]同步列表 -- db.mainInfos [跨服]活动服基础信息 -- db.matchList [跨服]分组列表 [index]={svrIndex1, svrIndex2...} -------------------------------------------------------------- local LuaMongo = _G.lua_mongo local DB = require("common.DB") local Config = require("Config") local ValleyExcel = require("excel.valley") local ValleyDefine = ValleyExcel.define[1] local MailExcel = require("excel.mail") local CommonDB = require("common.CommonDB") local Util = require("common.Util") local Lang = require("common.Lang") local Msg = require("core.Msg") local InnerMsg = require("core.InnerMsg") local ObjHuman = require("core.ObjHuman") local Broadcast = require("broadcast.Broadcast") local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local CombatLogic = require("combat.CombatLogic") local CombatDefine = require("combat.CombatDefine") local CombatPosLogic = require("combat.CombatPosLogic") local HeroGrid = require("hero.HeroGrid") local JjcActLogic = require("jjc.JjcActLogic") local MailManager = require("mail.MailManager") local MiddleConnect = require("middle.MiddleConnect") local RoleDBLogic = require("role.RoleDBLogic") local RoleLogic = require("role.RoleLogic") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") local ValleyTask = require("valley.ValleyTask") local ValleyMiddle = require("valley.ValleyMiddle") local HeroLogic = require("hero.HeroLogic") -- 活动状态 STATE_ACT_NO_OPEN = 0 -- 未开放 STATE_ACT_READY = 1 -- 休战 STATE_ACT_SIGN = 2 -- 报名 STATE_ACT_MATCH = 3 -- 匹配 STATE_ACT_EXPLORE = 4 -- 侦查 STATE_ACT_FIGHT = 5 -- 战斗(行军->准备->战斗) -- 战斗阶段的状态 STATE_FIGHT_END = 0 -- 结束 STATE_FIGHT_MOVE = 1 -- 行军 STATE_FIGHT_READY = 2 -- 准备/鼓舞 STATE_FIGHT_FIGHT = 3 -- 战斗 ROAD_MAX_CNT = 3 -- 一共有x路营地 ROAD_POINT_CNT = 3 -- 每路有x个目标点 MAX_INSPIRE_CNT = 100 -- 鼓舞进度条上限 TIMER_SEND_DATA = 3 -- 每次发送x个玩家数据到跨服 local fakeHuman = {} -- 获得活动最新状态 state, stateEndTime, stateStartTime local function getNewState() local nowTime = os.time() local weekStartTime = Util.getWeekStartTime(nowTime) local scf = ValleyDefine.startTime local startTime = weekStartTime + (scf.week - 1) * 86400 + scf.hour * 3600 + scf.min * 60 local ecf = ValleyDefine.endTime local endTime = weekStartTime + (ecf.week - 1) * 86400 + ecf.hour * 3600 + ecf.min * 60 if startTime <= nowTime and nowTime < endTime then local signEndTime = startTime + ValleyDefine.signTime if nowTime < signEndTime then return STATE_ACT_SIGN, signEndTime, startTime end local matchEndTime = signEndTime + ValleyDefine.matchTime if nowTime < matchEndTime then return STATE_ACT_MATCH, matchEndTime, signEndTime end local exploreEndTime = matchEndTime + ValleyDefine.exploreTime if nowTime < exploreEndTime then return STATE_ACT_EXPLORE, exploreEndTime, matchEndTime end return STATE_ACT_FIGHT, endTime, exploreEndTime end if nowTime < startTime then return STATE_ACT_READY, startTime, endTime - 7 * 86400 end return STATE_ACT_READY, startTime + 7 * 86400, endTime end -- 获取活动当前状态(显示用) function getState() if not _G.is_middle and MiddleConnect.IS_MIDDLE_CONNECT ~= true then return STATE_ACT_NO_OPEN, 0 end local commonDB = getCommonDB() if not commonDB.state then onTimer() commonDB = getCommonDB() end local leftTime = math.max(commonDB.endTime - os.time(), 0) return commonDB.state, leftTime, commonDB.startTime end -- 获取轮次信息 第x轮 阶段 local function getNewRound(startTime) local time = math.max(os.time() - startTime, 1) local roundMaxTime = ValleyDefine.roundMoveTime + ValleyDefine.roundReadyTime + ValleyDefine.roundFightTime local round = math.ceil(time / roundMaxTime) local roundTime = time % roundMaxTime local roundStateEndTime = startTime + (round - 1) * roundMaxTime if roundTime < ValleyDefine.roundMoveTime then return round, STATE_FIGHT_MOVE, roundStateEndTime + ValleyDefine.roundMoveTime end if roundTime < ValleyDefine.roundMoveTime + ValleyDefine.roundReadyTime then return round, STATE_FIGHT_READY, roundStateEndTime + ValleyDefine.roundMoveTime + ValleyDefine.roundReadyTime end return round, STATE_FIGHT_FIGHT, roundStateEndTime + roundMaxTime end -- 获取活动当前轮次 function getRound() local commonDB = getCommonDB() if not commonDB.state then onTimer() commonDB = getCommonDB() end return commonDB.round, commonDB.roundState, commonDB.roundStateEndTime end -- 是否开放 function isOpen(human) local state, leftTime, startTime = getState() if state == STATE_ACT_NO_OPEN then -- 跨服未启动 return Broadcast.sendErr(human, Lang.MIDDLE_SVR_ERR_CONNECT) end -- 判断开放等级+开服天数 -- if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_10013, true) then -- return -- end return state, leftTime, startTime end ----------------------------------------------- db -------------------------------------------------- -- 清空 function cleanDB() local commonDB = getCommonDB() commonDB.round = nil commonDB.roundState = nil commonDB.signList = nil commonDB.roadList = nil commonDB.roadListSend = nil commonDB.mainInfos = nil commonDB.matchList = nil saveCommonDB(commonDB) LuaMongo.remove(DB.db_valley) LuaMongo.remove(DB.db_valley_record) end function saveCommonDB(data) data = data or {} CommonDB.updateValue(CommonDB.KEY_VALLEY, data) end local TEMP_COMMONDB = {} function getCommonDB() return CommonDB.getValueByKey(CommonDB.KEY_VALLEY) or TEMP_COMMONDB end -- 是否报名 function getSignData(uuid) local commonDB = getCommonDB() if not commonDB.signList then return end return commonDB.signList[uuid] end -- 设置报名 function addSignData(human) local uuid = human.db._id local commonDB = getCommonDB() commonDB.signList = commonDB.signList or {} if commonDB.signList[uuid] then return end local signData = {} signData.roadIndex = 0 -- 入驻x路 signData.exploreCnt = 0 -- 侦查次数 signData.exploreItems = nil -- 侦查未领取道具 [itemID] = itemCnt signData.exploreLogs = {} -- 侦查日志 [index] = id signData.zhandouli = human.db.zhandouli commonDB.signList[uuid] = signData saveCommonDB(commonDB) return signData end -- 获取入驻哪一路 function getRoadIndex(uuid) local signData = getSignData(uuid) if not signData then return end return signData.roadIndex end -- 获取某路的入驻列表 function getRoadUuids(roadIndex) local commonDB = getCommonDB() if not commonDB.roadList then return end return commonDB.roadList[roadIndex] end -- 从某路移除 function delFromRoad(uuid, noSave) local signData = getSignData(uuid) if not signData or signData.roadIndex < 1 then return end local roadIndex = signData.roadIndex local uuids = getRoadUuids(roadIndex) local uuidsLen = uuids and #uuids or 0 local cnt = 0 for i = 1, uuidsLen do local tuuid = uuids[i] uuids[i] = nil if tuuid ~= uuid then cnt = cnt + 1 uuids[cnt] = tuuid end end signData.roadIndex = 0 if not noSave then saveCommonDB(commonDB) end return roadIndex end -- 入驻某路 function addToRoad(uuid, roadIndex, noSave) delFromRoad(uuid, true) local signData = getSignData(uuid) if not signData then return end if signData.roadIndex > 0 then return end if roadIndex < 1 then return end signData.roadIndex = roadIndex local commonDB = getCommonDB() commonDB.roadList = commonDB.roadList or {} if not commonDB.roadList[roadIndex] then commonDB.roadList[roadIndex] = {} end local cnt = #commonDB.roadList[roadIndex] commonDB.roadList[roadIndex][cnt + 1] = uuid if not noSave then saveCommonDB(commonDB) end return roadIndex end -- 生成侦查道具 function randomExploreID() local weight = 0 for _, config in pairs(ValleyExcel.explore) do weight = weight + config.weight end if weight < 1 then return end local r = math.random(1, weight) for id, config in pairs(ValleyExcel.explore) do if r <= config.weight then return id, config end r = r - config.weight end end -- 平均战力 local function getMainInfoZDL() local commonDB = getCommonDB() if not commonDB.signList then return 0 end local cnt = 0 local sum = 0 for _, signData in pairs(commonDB.signList) do cnt = cnt + 1 sum = sum + signData.zhandouli end if cnt > 0 then return math.floor(sum / cnt) end return 0 end -- 创建服基础信息 function createMainInfo() local mainInfo = {} mainInfo.svrIndex = Config.SVR_INDEX mainInfo.svrName = Config.SVR_NAME mainInfo.zhandouli = getMainInfoZDL() mainInfo.inspireCnt = nil -- 鼓舞次数 mainInfo.inspireList = nil -- 鼓舞列表 mainInfo.targetSvrIndex = nil -- 对手服务器 0表示没有对手 mainInfo.roadList = {} -- 入驻列表 [roadIndex][index] = uuid mainInfo.fightIndexList = {} -- 出战索引 [roadIndex] = index mainInfo.fightIndexChange = nil -- 本轮结束是否换人 [roadIndex] = boolean (true表示换人) mainInfo.fightWinCnt = 0 -- 本轮胜利场数 mainInfo.fightFailCnt = 0 -- 本轮失败场数 mainInfo.fightResult = nil -- 本轮战斗结果 [roadIndex] = 胜负 mainInfo.fightVideo = nil -- 本轮战斗录像 [roadIndex] = videoUuid mainInfo.moveList = {} -- 移动列表 [uuid] = pos mainInfo.logReads = {} -- 日志读取列表 [uuid] = boolean mainInfo.logs = {} -- 日志列表 [index] = videoUuid mainInfo.board = {} -- 排行榜 [rank] = uuid return mainInfo end -- 创建角色数据 function createPlayerData(uuid, roadIndex) local db = RoleDBLogic.getDb(uuid, RoleLogic.getCombatField()) if not db then return end fakeHuman.db = db local combatType = CombatDefine.COMBAT_TYPE17 local objList, helpList, rolebase, formation = CombatLogic.getHumanObjList(fakeHuman, combatType) if not objList then return end rolebase.tili = ValleyDefine.initTili -- 初始体力 每打完一场扣1 rolebase.winCnt = 0 -- 胜利场数 rolebase.name = "[" .. Config.SVR_NAME .. "]" .. rolebase.name -- 名字拼接上服务名前缀 rolebase.body = CombatLogic.getRoleBody(fakeHuman, combatType) -- 外显形象 rolebase.time = os.time() local playerData = {} playerData._id = uuid playerData.roadIndex = roadIndex playerData.rolebase = rolebase playerData.objList = objList playerData.helpList = helpList playerData.formation = formation return playerData end -- 根据鼓舞次数获取额外属性 function getAttrsUp(inspireCnt1, inspireCnt2, camp) local cnt = 0 if camp == CombatDefine.ATTACK_SIDE then cnt = inspireCnt1 - inspireCnt2 else cnt = inspireCnt2 - inspireCnt1 end cnt = math.min(cnt, ValleyDefine.inspireAttrCnt) if cnt < 1 then return end local attrsUp = {} for _, attr in ipairs(ValleyDefine.inspireAttr) do local attrUp = {} attrUp[1] = attr[1] attrUp[2] = attr[2] * cnt attrsUp[#attrsUp + 1] = attrUp end return attrsUp end ------------------------------------------------ msg -------------------------------------------------- -- 默认信息 local TEMP_MAIN_INFO = nil local function getMainInfoCache() if not TEMP_MAIN_INFO then TEMP_MAIN_INFO = createMainInfo() end return TEMP_MAIN_INFO end -- 营地是否被攻破 function isRoadDie(data, roadIndex) if not data then return true end local fightIndex = data.fightIndexList[roadIndex] or 1 local list = data.roadList[roadIndex] local listLen = list and #list or 0 return fightIndex > listLen end -- 获取破营数 function getMainStar(data1, data2) local star = 0 for i = 1, ROAD_MAX_CNT do -- (敌方阵营被攻破)敌方某路没人,己方还有人 if isRoadDie(data2, i) and not isRoadDie(data1, i) then star = star + 1 end end return star end -- 封装主界面基础信息 local function fontMainInfo(net, data1, data2) net.svrName = data1 and data1.svrName or "" net.star = getMainStar(data1, data2) net.roadStates[0] = ROAD_MAX_CNT for i = 1, ROAD_MAX_CNT do net.roadStates[i] = 0 -- (己方阵营被攻破)己方某路没人,敌方还有人 if isRoadDie(data1, i) and not isRoadDie(data2, i) then net.roadStates[i] = 1 end end end -- 主界面查询 local TEMP_QUERY_DATA = {} function query(human) local state, leftTime = isOpen(human) if not state then return end if state ~= STATE_ACT_FIGHT then return sendQuery(human.db._id, TEMP_QUERY_DATA) end local msgInner = InnerMsg.lw.LW_VALLEY_QUERY msgInner.uuid = uuid InnerMsg.sendMsg(0, msgInner) end -- 发送主界面信息 function sendQuery(uuid, data) local human = ObjHuman.onlineUuid[uuid] if not human then return end local state, leftTime = data.state, data.leftTime if not state or not leftTime then state, leftTime = getState() end if not state then return end local msgRet = Msg.gc.GC_VALLEY_QUERY local dataNet = msgRet.data dataNet.state = state dataNet.leftTime = leftTime dataNet.taskRed = ValleyTask.isRed(human) and 1 or 0 dataNet.logRed = data.logRed and 1 or 0 local mainInfo1 = data.mainInfo1 or getMainInfoCache() fontMainInfo(dataNet.info1, mainInfo1, data.mainInfo2) fontMainInfo(dataNet.info2, data.mainInfo2, mainInfo1) -- 是否报名 local signData = getSignData(uuid) dataNet.isSign = signData and 1 or 0 dataNet.roadIndex = signData and signData.roadIndex or 0 -- 探索阶段额外信息 dataNet.exploreData[0] = 0 if state == STATE_ACT_EXPLORE then dataNet.exploreData[0] = 1 local exploreDataNet = dataNet.exploreData[1] exploreDataNet.time = ValleyDefine.exploreTime - leftTime exploreDataNet.maxTime = ValleyDefine.exploreTime exploreDataNet.exploreRed = isRedExplore(human) and 1 or 0 end -- 战斗阶段额外信息 dataNet.fightData[0] = 0 if state == STATE_ACT_FIGHT then dataNet.fightData[0] = 1 local fightDataNet = dataNet.fightData[1] fightDataNet.fightState = data.roundState or 0 fightDataNet.leftTime = (data.roundStateEndTime - os.time()) or 0 fightDataNet.players[0] = data.players and #data.players or 0 for i = 1, fightDataNet.players[0] do Util.copyTableSimple(data.players[i], fightDataNet.players[i]) end end -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 报名 function sign(human) local state = isOpen(human) if not state then return end -- 是否报名阶段 if state ~= STATE_ACT_SIGN then return Broadcast.sendErr(human, Lang.VALLEY_SIGN_ERR_TIME) end -- 判断是否已报名 if getSignData(human.db._id) then return Broadcast.sendErr(human, Lang.VALLEY_SIGN_ERR_HAD) end -- 未报名生成报名信息 addSignData(human) -- 初始队伍取征战的阵容 CombatPosLogic.copyCombatHeros(human, CombatDefine.COMBAT_TYPE1, CombatDefine.COMBAT_TYPE17) Broadcast.sendErr(human, Lang.VALLEY_SIGN_OK) Msg.send(Msg.gc.GC_VALLEY_SIGN, human.fd) end -- 封装各路入驻角色信息 function fontRoadPlayer(net, uuid) local db = RoleDBLogic.getDb(uuid, RoleLogic.getCombatField()) if not db then return end fakeHuman.db = db net.uuid = uuid net.name = "[" .. Config.SVR_NAME .. "]" .. db.name net.tili = ValleyDefine.initTili net.heroList[0] = 0 -- 报名了才显示默认队伍 local heroIndexs = CombatPosLogic.getCombatHeros(fakeHuman, CombatDefine.COMBAT_TYPE17) if heroIndexs and getSignData(uuid) then for pos = 1, CombatDefine.COMBAT_HERO_CNT do local uuid = heroIndexs[pos] local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid) if heroGrid and type(heroGrid) == "table" then net.heroList[0] = net.heroList[0] + 1 HeroGrid.makeHeroSimple(net.heroList[net.heroList[0]], heroGrid, pos) end end end net.zhandouli = CombatPosLogic.getCombatHeroZDL(fakeHuman, CombatDefine.COMBAT_TYPE17) return true end -- 某路的入驻信息 function queryRoad(human, camp, roadIndex) local state = isOpen(human) if not state then return end if roadIndex < 1 or roadIndex > ROAD_MAX_CNT then return end if camp ~= 1 and camp ~= 2 then return end if state == STATE_ACT_READY then -- 休战阶段是看不了的 return Broadcast.sendErr(human, Lang.VALLEY_ERR_READY) end -- 只有战斗阶段可以查看敌方营地信息 if state ~= STATE_ACT_FIGHT and camp ~= CombatDefine.ATTACK_SIDE then returnBroadcast.sendErr(human, Lang.VALLEY_ROAD_ERR_CAMP) end if state == STATE_ACT_SIGN then -- 报名阶段显示本服数据即可 return sendRoadQuery(human.db._id, camp, roadIndex) end local msgInner = InnerMsg.lw.LW_VALLEY_ROAD_QUERY msgInner.uuid = human.db._id msgInner.camp = camp msgInner.roadIndex = roadIndex InnerMsg.sendMsg(0, msgInner) end -- 发送入驻信息 function sendRoadQuery(uuid, camp, roadIndex, playerList, myData) local human = ObjHuman.onlineUuid[uuid] if not human then return end local msgRet = Msg.gc.GC_VALLEY_ROAD_QUERY msgRet.state = getState() msgRet.camp = camp msgRet.roadIndex = roadIndex msgRet.myRoadIndex = getRoadIndex(uuid) or 0 msgRet.list[0] = 0 if playerList then msgRet.cnt = playerList.cnt or 0 msgRet.list[0] = #playerList for i = 1, msgRet.list[0] do Util.copyTableSimple(playerList[i], msgRet.list[i]) end else local uuids = getRoadUuids(roadIndex) local uuidsLen = uuids and #uuids or 0 msgRet.cnt = uuidsLen for i = 1, uuidsLen do if msgRet.list[0] >= #msgRet.list then break end local uuid = uuids[i] if fontRoadPlayer(msgRet.list[msgRet.list[0] + 1], uuid) then msgRet.list[0] = msgRet.list[0] + 1 end end end if myData and myData.uuid then Util.copyTableSimple(myData, msgRet.myData) else fontRoadPlayer(msgRet.myData, uuid) end msgRet.isSign = getSignData(uuid) and 1 or 0 -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 发送入驻/退出路线 local function sendRoadChange(human, roadIndex) local msgRet = Msg.gc.GC_VALLEY_ROAD_CHANGE msgRet.roadIndex = roadIndex Msg.send(msgRet, human.fd) end -- 修改入驻路线 function changeRoad(human, roadIndex) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_SIGN then return Broadcast.sendErr(human, Lang.VALLEY_CHANGE_ROAD_ERR_TIME) end if roadIndex < 1 or roadIndex > ROAD_MAX_CNT then return end if not getSignData(human.db._id) then --先报名 return Broadcast.sendErr(human, Lang.VALLEY_ERR_SIGN) end if roadIndex == 0 then -- 退出入驻 local oldRoadIndex = delFromRoad(human.db._id) if oldRoadIndex and oldRoadIndex > 0 then sendRoadChange(human, roadIndex) end else -- 入驻某路 if addToRoad(human.db._id, roadIndex) then sendRoadQuery(human, roadIndex) sendRoadChange(human, roadIndex) end end end -- 自动入驻路线 优先选人最少的 -- 报名了,但还没入驻 function autoChangeRoad(uuid) if getRoadIndex(uuid) ~= 0 then return end local commonDB = getCommonDB() local minCnt = nil local minCntRoadInex = nil for i = 1, ROAD_MAX_CNT do local roadList = commonDB.roadList[i] local cnt = roadList and #roadList or 0 if minCnt == nil or cnt < minCnt then minCnt = cnt minCntRoadInex = i end end if not minCntRoadInex then return end addToRoad(uuid, minCntRoadInex, true) end -- 刷新侦查列表 function refreshExplore(signData, exploreCnt) local isChange = nil for i = signData.exploreCnt + 1, exploreCnt do signData.exploreCnt = i local id, config = randomExploreID() if id and config then signData.exploreLogs[#signData.exploreLogs + 1] = id signData.exploreItems = signData.exploreItems or {} local oldItemCnt = signData.exploreItems[config.itemID] or 0 signData.exploreItems[config.itemID] = oldItemCnt + config.itemCnt end isChange = true end if isChange then saveCommonDB(getCommonDB()) end end -- 是否有侦查红点(有奖励可领取) function isRedExplore(human) local state, _, startTime = isOpen(human) if not state then return end if state ~= STATE_ACT_EXPLORE then return end local signData = getSignData(human.db._id) if not signData then return end local exploreCnt = math.floor((os.time() - startTime) / ValleyDefine.exploreItemTime) refreshExplore(signData, exploreCnt) if signData.exploreItems then return true end end -- 侦查界面查询 function sendExploreQuery(human) local state, _, startTime = isOpen(human) if not state then return end if state ~= STATE_ACT_EXPLORE then return Broadcast.sendErr(human, Lang.VALLEY_EXPLORE_ERR_TIME) end local signData = getSignData(human.db._id) if not signData then return Broadcast.sendErr(human, Lang.VALLEY_ERR_SIGN) end local exploreCnt = math.floor((os.time() - startTime) / ValleyDefine.exploreItemTime) refreshExplore(signData, exploreCnt) local msgRet = Msg.gc.GC_VALLEY_EXPLORE_QUERY msgRet.time = os.time() msgRet.logs[0] = #signData.exploreLogs for i = 1, msgRet.logs[0] do local net = msgRet.logs[i] local id = signData.exploreLogs[i] local config = ValleyExcel.explore[id] net.time = startTime + ValleyDefine.exploreItemTime * i net.content = Util.format(config.content, ItemDefine.getValue(config.itemID, "name"), config.itemCnt) end msgRet.items[0] = 0 if signData.exploreItems then for itemID, itemCnt in pairs(signData.exploreItems) do msgRet.items[0] = msgRet.items[0] + 1 Grid.makeItem(msgRet.items[msgRet.items[0]], itemID, itemCnt) end end Msg.send(msgRet, human.fd) end -- 领取侦查奖励 function getExplore(human) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_EXPLORE then return Broadcast.sendErr(human, Lang.VALLEY_EXPLORE_ERR_TIME) end local signData = getSignData(human.db._id) if not signData then return Broadcast.sendErr(human, Lang.VALLEY_ERR_SIGN) end local exploreCnt = math.floor((os.time() - startTime) / ValleyDefine.exploreItemTime) refreshExplore(signData, exploreCnt) local exploreItems = signData.exploreItems if not exploreItems then return Broadcast.sendErr(human, Lang.VALLEY_EXPLORE_GET_ERR_ITEMS) end signData.exploreItems = nil saveCommonDB(getCommonDB()) for itemID, itemCnt in pairs(exploreItems) do BagLogic.addItem(human, itemID, itemCnt, "valley") end BagLogic.sendItemGetList(human, exploreItems, "valley") sendExploreQuery(human) end -- 封装鼓舞基本信息 local function fontInspireBase(net, mainInfo) net.svrName = mainInfo and mainInfo.svrName or "" net.cnt = mainInfo and mainInfo.inspireCnt or 0 net.maxCnt = MAX_INSPIRE_CNT end local function fontInspireData(dataNet, data) dataNet.round = data.round fontInspireBase(dataNet.base1, data.mainInfo1) fontInspireBase(dataNet.base2, data.mainInfo2) dataNet.inspireItems[0] = 2 Grid.makeItem(dataNet.inspireItems[1], ValleyDefine.inspireItem1[1], ValleyDefine.inspireItem1[2]) Grid.makeItem(dataNet.inspireItems[2], ValleyDefine.inspireItem2[1], ValleyDefine.inspireItem2[2]) dataNet.selectIndex = data.selectIndex or 0 end -- 鼓舞查询 function queryInspire(human) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_FIGHT then return Broadcast.sendErr(human, Lang.VALLEY_INSPIRE_ERR_TIME) end local msgInner = InnerMsg.lw.LW_VALLEY_INSPIRE_QUERY msgInner.uuid = human.db._id InnerMsg.sendMsg(0, msgInner) end -- 鼓舞 function selectInspire(human, selectIndex) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_FIGHT then return Broadcast.sendErr(human, Lang.VALLEY_INSPIRE_ERR_TIME) end -- 判断花费 local useItem = ValleyDefine["inspireItem" .. selectIndex] if not useItem then return end -- 选择鼓舞不存在 local itemID = useItem[1] local itemCnt = useItem[2] if not BagLogic.checkItemCnt(human, itemID, itemCnt) then return end -- 通知跨服 local msgInner = InnerMsg.lw.LW_VALLEY_INSPIRE msgInner.uuid = human.db._id InnerMsg.sendMsg(0, msgInner) end -- 观战面板查询 function queryFight(human, roadIndex) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_FIGHT then return Broadcast.sendErr(human, Lang.VALLEY_FIGHT_ERR_TIME) end if roadIndex < 1 or roadIndex > ROAD_MAX_CNT then return end local msgInner = InnerMsg.lw.LW_VALLEY_FIGHT_QUERY msgInner.uuid = human.db._id msgInner.roadIndex = roadIndex InnerMsg.sendMsg(0, msgInner) end -- 观战 function playFight(human, videoUuid) local state = isOpen(human) if not state then return end if state ~= STATE_ACT_FIGHT then return Broadcast.sendErr(human, Lang.VALLEY_FIGHT_ERR_TIME) end if videoUuid == "" then return Broadcast.sendErr(human, Lang.VALLEY_FIGHT_ERR_DOING) end local msgInner = InnerMsg.lw.LW_VALLEY_PLAY_FIGHT msgInner.uuid = human.db._id msgInner.videoUuid = videoUuid InnerMsg.sendMsg(0, msgInner) end -- 日志查看 function queryLog(human, roadIndex) local state = isOpen(human) if not state then return end if roadIndex < 0 or roadIndex > ROAD_MAX_CNT then return end local msgInner = InnerMsg.lw.LW_VALLEY_LOG_QUERY msgInner.uuid = human.db._id msgInner.roadIndex = roadIndex InnerMsg.sendMsg(0, msgInner) end -- 排行榜查看 function queryBoard(human, camp) local state = isOpen(human) if not state then return end if camp ~= 1 and camp ~= 2 then return end local msgInner = InnerMsg.lw.LW_VALLEY_BOARD_QUERY msgInner.uuid = human.db._id msgInner.camp = camp InnerMsg.sendMsg(0, msgInner) end -- 可否打开上阵面板 function checkCombatPos(human) local state = isOpen(human) if not state then return end -- 未达到开放条件 if state == STATE_ACT_FIGHT then -- 开打了,不可以 return Broadcast.sendErr(human, Lang.VALLEY_COMBAT_POS_ERR_TIME) end if state ~= STATE_ACT_SIGN then local roadIndex = getRoadIndex(uuid) if not roadIndex then -- 错过报名阶段,还没报名,不让改阵容 return Broadcast.sendErr(human, Lang.VALLEY_COMBAT_POS_ERR_SIGN) end if roadIndex == 0 then -- 错过报名阶段,没入驻,不让改阵容 return Broadcast.sendErr(human, Lang.VALLEY_COMBAT_POS_ERR_ROAD) end end return true end -- 刷新上阵信息 function onUpdate(human) local uuid = human.db._id local roadIndex = getRoadIndex(uuid) if not roadIndex then return end local state = getState() if state == STATE_ACT_FIGHT then return end sendLWRoadPlayer(uuid, roadIndex) end -------------------------------------- middle ------------------------------------------- -- 主界面 function WL_VALLEY_QUERY(uuid, data) sendQuery(uuid, data) end -- 营地查询 function WL_VALLEY_ROAD_QUERY(uuid, camp, roadIndex, playerList, myData) sendRoadQuery(uuid, camp, roadIndex, playerList, myData) end -- 鼓舞界面返回 function WL_VALLEY_INSPIRE_QUERY(uuid, data) local human = ObjHuman.onlineUuid[uuid] if not human then return end local msgRet = Msg.gc.GC_VALLEY_INSPIRE_QUERY msgRet.leftTime = data.leftTime fontInspireData(msgRet.data, data) Msg.send(msgRet, human.fd) end -- 鼓舞 function WL_VALLEY_INSPIRE(uuid, selectIndex) local human = ObjHuman.onlineUuid[uuid] if not human then return end -- 判断花费 local useItem = ValleyDefine["inspireItem" .. selectIndex] if not useItem then return end -- 选择鼓舞不存在 local itemID = useItem[1] local itemCnt = useItem[2] if not BagLogic.checkItemCnt(human, itemID, itemCnt) then return end BagLogic.delItem(human, itemID, itemCnt, "valley_inspire") end -- 观战界面 function WL_VALLEY_FIGHT_QUERY(uuid, data) local human = ObjHuman.onlineUuid[uuid] if not human then return end local msgRet = Msg.gc.GC_VALLEY_FIGHT_QUERY msgRet.fightState = data.fightState or 0 fontInspireData(msgRet.inspireData, data) msgRet.fightPlayers[0] = data.fightPlayers and #data.fightPlayers or 0 for i = 1, msgRet.fightPlayers[0] do Util.copyTableSimple(data.fightPlayers[i], msgRet.fightPlayers[i]) end msgRet.fightBase[0] = data.fightBase and #data.fightBase or 0 for i = 1, msgRet.fightBase[0] do Util.copyTableSimple(data.fightBase[i], msgRet.fightBase[i]) end msgRet.videoUuid = data.videoUuid or "" Msg.send(msgRet, human.fd) end -- 观战 function WL_VALLEY_PLAY_FIGHT(uuid, combatInfo) local human = ObjHuman.onlineUuid[uuid] if not human then return end CombatLogic.repeatCombat(human, combatInfo) end -- 开打 function WL_VALLEY_COMBAT_BEGIN(svrIndex, roadIndex, round, inspireCnt1, inspireCnt2, playerData1, playerData2) -- 开打 local cbParam = {} cbParam.svrIndex = svrIndex cbParam.roadIndex = roadIndex cbParam.inspireCnt1 = inspireCnt1 cbParam.inspireCnt2 = inspireCnt2 cbParam.round = round cbParam.hpRateListAtk = playerData1.hpRateList cbParam.hpRateListDef = playerData2.hpRateList local param = {} param.attacker = playerData1.objList param.atkHelp = playerData1.helpList param.atkRBase = playerData1.rolebase param.atkFormation = playerData1.formation param.defender = playerData2.objList param.defHelp = playerData2.helpList param.defRBase = playerData2.rolebase param.defFormation = playerData2.formation fakeHuman.db = nil CombatLogic.combatBegin(fakeHuman, 1001, param, CombatDefine.COMBAT_TYPE17, cbParam, true) end -- 战斗前加属性 function onFightBegin(human, cbParam) local attrsUp1 = getAttrsUp(cbParam.inspireCnt1, cbParam.inspireCnt2, CombatDefine.ATTACK_SIDE) local attrsUp2 = getAttrsUp(cbParam.inspireCnt1, cbParam.inspireCnt2, CombatDefine.DEFEND_SIDE) for index = 1, CombatDefine.COMBAT_HERO_CNT do -- 攻击 local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index) local atkObj = CombatImpl.objList[atkPos] if atkObj then atkObj.isSysAttrChange = true if attrsUp1 then local initAttr = atkObj.initAttr --基础属性 for _, attrUp in ipairs(attrsUp1) do initAttr[attrUp[1]] = initAttr[attrUp[1]] + attrUp[2] end end end -- 防守 local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, index) local defObj = CombatImpl.objList[defPos] if defObj then defObj.isSysAttrChange = true if attrsUp2 then local initAttr = defObj.initAttr --基础属性 for _, attrUp in ipairs(attrsUp2) do initAttr[attrUp[1]] = initAttr[attrUp[1]] + attrUp[2] end end end end end -- 战斗结束回调 function onFightEnd(human, result, combatType, cbParam, combatInfo, isSaodang) print("fight end", result, combatInfo, result) -- 如果两边都没死,按照 calcCombatResult(combatInfo) combatInfo.inspireCnt1 = cbParam.inspireCnt1 combatInfo.inspireCnt2 = cbParam.inspireCnt2 combatInfo.roadIndex = roadIndex combatInfo.round = round local msgInner = InnerMsg.lw.LW_VALLEY_COMBATINFO msgInner.svrIndex = cbParam.svrIndex msgInner.combatInfo = combatInfo InnerMsg.sendMsg(0, msgInner) end -- 刷新记录的血量+双方未死时,重新定义胜负(血量多胜出) function calcCombatResult(combatInfo) local hpRateListAtk = {} local hpRateListDef = {} local hpSumAtk = 0 local hpSumDef = 0 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 hpRateListAtk[index] = hpRate hpSumAtk = math.max(hp, 0) + hpSumAtk 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 hpRateListDef[index] = hpRate hpSumDef = math.max(hp, 0) + hpSumDef end end combatInfo.isWin = hpSumAtk >= hpSumDef combatInfo.hpRateListAtk = hpRateListAtk combatInfo.hpRateListDef = hpRateListDef end -- 所有属性计算完毕,重新设置血量(攻击) function calcAttr(side, index, obj, cbParam) local hpRateList = nil if side == CombatDefine.ATTACK_SIDE then hpRateList = cbParam.hpRateListAtk else hpRateList = cbParam.hpRateListDef end if not hpRateList then return end local hpRate = hpRateList[index] if not hpRate then return end local hpMax = CombatObj.getHpMax(obj) obj.hp = math.ceil(hpRate * hpMax) end -- 战斗刷新 如果客户端处于观战面板且对应营地 重新请求CG_VALLEY_FIGHT_QUERY function WL_VALLEY_FIGHT_QUERY_REFRESH(roadIndex) local msgRet = Msg.gc.GC_VALLEY_FIGHT_QUERY_REFRESH msgRet.roadIndex = roadIndex Msg.sendWorld(msgRet) end -- 日志 function WL_VALLEY_LOG_QUERY(uuid, roadIndex, logs) local human = ObjHuman.onlineUuid[uuid] if not human then return end local msgRet = Msg.gc.GC_VALLEY_LOG_QUERY msgRet.roadIndex = roadIndex msgRet.logs[0] = #logs for i = 1, msgRet.logs[0] do Util.copyTableSimple(logs[i], msgRet.logs[i]) end -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 排行榜 function WL_VALLEY_BOARD_QUERY(uuid, camp, list, myData) local human = ObjHuman.onlineUuid[uuid] if not human then return end local msgRet = Msg.gc.GC_VALLEY_BOARD_QUERY msgRet.camp = camp Util.copyTableSimple(myData, msgRet.myData) if myData.roleBase == nil then msgRet.myData.killCnt = 0 RoleLogic.makeRoleBase(human.db, msgRet.myData.roleBase) end msgRet.list[0] = #list for i = 1, msgRet.list[0] do Util.copyTableSimple(list[i], msgRet.list[i]) end -- Msg.trace(msgRet) Msg.send(msgRet, human.fd) end -- 计算破营奖励 function calcRoadItems(roadItems, items, cnt) if cnt < 1 then return end for _, item in pairs(items) do local itemID = item[1] local itemCnt = item[2] * cnt local selectIndex = #roadItems + 1 for index, item2 in ipairs(roadItems) do if item2[1] == itemID then selectIndex = index break end end roadItems[selectIndex] = roadItems[selectIndex] or {} roadItems[selectIndex][1] = itemID roadItems[selectIndex][2] = (roadItems[selectIndex][2] or 0) + itemCnt end return roadItems end -- 破营+杀敌奖励+刷新成就 function WL_VALLEY_FINAL_RESULT(killList, winCnt, failCnt, tieCnt) local roadMailConfig = MailExcel.mail[114] local roadContent = Util.format(roadMailConfig.content, winCnt, failCnt, tieCnt) local killMailConfig = MailExcel.mail[115] local roadItems = {} calcRoadItems(roadItems, ValleyDefine.roadWinItem, winCnt) calcRoadItems(roadItems, ValleyDefine.roadFailItem, failCnt) calcRoadItems(roadItems, ValleyDefine.roadTieItem, tieCnt) for uuid, killCnt in pairs(killList) do -- 杀敌奖励 local killConfig = ValleyExcel.kill[killCnt] if killConfig then local content = Util.format(killMailConfig.content, killCnt) MailManager.add(MailManager.SYSTEM, uuid, killMailConfig.title, content, killConfig.reward, killMailConfig.senderName) end -- 破营奖励 MailManager.add(MailManager.SYSTEM, uuid, roadMailConfig.title, roadContent, roadItems, roadMailConfig.senderName) -- 成就刷新 ValleyTask.updateValue(uuid, killCnt, winCnt) end end -- 每轮鼓舞奖励 function WL_VALLEY_INSPIRE_RESULT(inspireList, winCnt, failCnt) local config = ValleyExcel.inspire[winCnt] if not config then return end local msgRet = Msg.gc.GC_VALLEY_INSPIRE_RESULT msgRet.winCnt = winCnt msgRet.failCnt = failCnt for uuid, selectIndex in pairs(inspireList) do local human = ObjHuman.onlineUuid[uuid] local inspireItem = ValleyDefine["inspireItem" .. selectIndex] if human and inspireItem then BagLogic.addItem(human, inspireItem[1], inspireItem[2], "valley_inspire") msgRet.items[0] = 1 Grid.makeItem(msgRet.items[1], inspireItem[1], inspireItem[2]) Msg.send(msgRet, human.fd) end end end ------------------------------------- 活动状态变化 ------------------------------------------ -- 发送角色数据 function sendLWRoadPlayer(uuid, roadIndex) local playerData = createPlayerData(uuid, roadIndex) if not playerData then return end local msgInner = InnerMsg.lw.LW_VALLEY_ROAD_PLAYER msgInner.playerData = playerData InnerMsg.sendMsg(0, msgInner) end -- 数据上传跨服+匹配对手 function onActMatch() if _G.is_middle then return end local commonDB = getCommonDB() -- 未入驻的自动入驻 if commonDB.signList then for uuid, roadIndex in pairs(commonDB.signList) do if roadIndex == 0 then autoChangeRoad(uuid) end end end commonDB.roadListSend = {} if commonDB.roadList then for roadIndex, list in pairs(commonDB.roadList) do for _, uuid in ipairs(list) do local data = {} data.uuid = uuid data.roadIndex = roadIndex commonDB.roadListSend[#commonDB.roadListSend + 1] = data end end end saveCommonDB(commonDB) local msgInner = InnerMsg.lw.LW_VALLEY_MAIN_INFO msgInner.data = createMainInfo() InnerMsg.sendMsg(0, msgInner) end -- 匹配阶段定时器 function onTimerActMatch(commonDB) if not commonDB.roadListSend then return end local cnt = 0 local len = #commonDB.roadListSend for i = len, 1, -1 do if cnt >= TIMER_SEND_DATA then break end local data = commonDB.roadListSend[i] commonDB.roadListSend[i] = nil sendLWRoadPlayer(data.uuid, data.roadIndex) cnt = cnt + 1 end if #commonDB.roadListSend < 1 then commonDB.roadListSend = nil end saveCommonDB(commonDB) end -- 侦查开始/匹配结束 function onActExplore() if _G.is_middle then ValleyMiddle.onActExplore() end end -- 战斗开始 function onActFight() local commonDB = getCommonDB() commonDB.round = nil commonDB.roundState = nil commonDB.roundStateEndTime = nil saveCommonDB(commonDB) end -- 战斗阶段轮次状态切换 function onActRound(round, roundState) print("onActRound", round, roundState) if _G.is_middle then return ValleyMiddle.onActRound(round, roundState) end end -- 战斗阶段定时器 function onTimerActFight(commonDB) local round, roundState, roundStateEndTime = getNewRound(commonDB.startTime) commonDB.round = commonDB.round or 1 commonDB.roundState = commonDB.roundState or 0 if commonDB.round > round then return end if commonDB.round == round and commonDB.roundState >= roundState then return end local newRoundState = commonDB.roundState + 1 local newRound = commonDB.round if newRoundState > STATE_FIGHT_FIGHT then newRoundState = STATE_FIGHT_MOVE newRound = newRound + 1 end commonDB.round = newRound commonDB.roundState = newRoundState commonDB.roundStateEndTime = roundStateEndTime saveCommonDB(commonDB) onActRound(newRound, newRoundState) end -- 活动结束 function onActEnd() if _G.is_middle then return ValleyMiddle.onActEnd() end cleanDB() end -- 活动开始 function onActStart() if _G.is_middle then return ValleyMiddle.onActStart() end cleanDB() end -- 定时器 local TEMP_TIMER_STAMPTIME = nil local TEMP_TIMER_STAMPTIME2 = nil function onTimer() if not TEMP_TIMER_STAMPTIME then _, TEMP_TIMER_STAMPTIME, TEMP_TIMER_STAMPTIME2 = getNewState() end local nowTime = os.time() local commonDB = getCommonDB() if (not commonDB.endTime) or (commonDB.endTime <= nowTime) or (commonDB.endTime ~= TEMP_TIMER_STAMPTIME) or (commonDB.startTime ~= TEMP_TIMER_STAMPTIME2) then local oldState = commonDB.state local state, endTime, startTime = getNewState() commonDB.state = state commonDB.endTime = endTime commonDB.startTime = startTime TEMP_TIMER_STAMPTIME = endTime TEMP_TIMER_STAMPTIME2 = startTime saveCommonDB(commonDB) print("valley state",state, oldState, endTime) if state == STATE_ACT_READY then onActEnd() elseif state == STATE_ACT_MATCH then onActMatch() elseif state == STATE_ACT_FIGHT then onActFight() elseif state == STATE_ACT_EXPLORE then onActExplore() elseif state == STATE_ACT_SIGN then onActStart() end end -- 战斗阶段 if commonDB.state == STATE_ACT_FIGHT then onTimerActFight(commonDB) elseif commonDB.state == STATE_ACT_MATCH then onTimerActMatch(commonDB) end end -- 返回活动列表的状态 function getActState() if MiddleConnect.IS_MIDDLE_CONNECT ~= true then return JjcActLogic.STATE_NOOPEN, 0 end local state, leftTime = getState() if state == STATE_ACT_READY then return JjcActLogic.STATE_READY, leftTime end return JjcActLogic.STATE_START, leftTime end -- 描述 function getActDesc(desc) if MiddleConnect.IS_MIDDLE_CONNECT then return Lang.MIDDLE_SVR_ERR_CONNECT end return desc end