--恶魔广场副本 DevilSquare = {} -- @description 客户端请求面板数据 -- @param 玩家对象;请求参数 -- @return function DevilSquare.ReqGetPanelInfo(actor, msgData) local configId = tonumber(msgData) if configId == nil or configId <= 0 then error("DevilSquare.ReqGetPanelInfo param is wrong", msgData) return end local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId) local leftCount = getleftcountofactivity(actor, activityId) local activityInfo = getactivityinfo(activityId) local isOpen = activityInfo["open"] local nextOpenTime if isOpen then nextOpenTime = activityInfo["closetime"] else nextOpenTime = activityInfo["nextopentime"] end local resInfo = { configId, leftCount, isOpen, tostring(nextOpenTime) } sendluamsg(actor, LuaMessageIdToClient.RES_DEVIL_SQUARE_PANEL, resInfo) end -- @description 请求进入恶魔广场 -- @param 玩家对象;cfg_rep的id -- @return function DevilSquare.ReqEnterDevilSquare(actor, configId) --是否组队,组队需要拉队友 local personal = true local teamId = getbaseinfo(actor, "teamid") teamId = tostring(teamId) if teamId ~= "0" then local teamInfo = getteaminfo(actor, teamId) local size = #teamInfo["allteammemberinfo"] if size > 1 then personal = false end end if personal == false then --组队进入 DuplicateCommon.CallTeamMembersPrepare(actor, configId) else --个人进入 if DuplicateCommon.CheckEnterConditonCommon(actor, configId) ~= EnterLimitResultConst.ALLOW then return end --寻找是否有可进入的副本,如果没有创建副本 local mapId = DuplicateCommon.FindEnterableDupCommon(configId, 1) local x, y = DuplicateCommon.GetEnterPointXYCommon(configId) if mapId == 0 then mapId = DuplicateCommon.CreateDupMapCommon(actor, configId, true) end --回蓝回血 DuplicateCommon.RecoverHPMP(memberActor) DevilSquare.PlayerEnterDevilSquare(actor, mapId, x, y, configId) end end -- @description 组队进入副本 -- @param 玩家对象;队伍id;副本配置 -- @return function DevilSquare.DoTeamEnter(actor, teamId, configId) local teamInfo = getteaminfo(actor, teamId) local members = teamInfo["allteammemberinfo"] for index, memberInfo in ipairs(members) do local memberId = memberInfo["rid"] local memberActor = getactor(actor, memberId) local check = DuplicateCommon.CheckEnterConditonCommon(memberActor, configId) if check ~= EnterLimitResultConst.ALLOW then error("组队进入成员条件不满足" .. memberId) return end end local memberActors = {} --扣除次数;扣除道具 for index, memberInfo in ipairs(members) do local memberId = memberInfo["rid"] local memberActor = getactor(actor, memberId) DevilSquare.RemoveItemBeforeEnter(memberActor, configId) table.insert(memberActors, memberActor) --回蓝回血 DuplicateCommon.RecoverHPMP(memberActor) end --组队进入 local size = #members --寻找是否有可进入的副本,如果没有创建副本 local mapId = DuplicateCommon.FindEnterableDupCommon(configId, size) local x, y = DuplicateCommon.GetEnterPointXYCommon(configId) if mapId == 0 then mapId = DuplicateCommon.CreateDupMapCommon(actor, configId, true) end enterduplicate(actor, mapId, x, y, memberActors) end -- @description 进入副本扣除次数和道具 -- @param -- @return function DevilSquare.RemoveItemBeforeEnter(actor, configId) -- 扣除次数 local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId) reduceactivitytimes(actor, activityId) -- 扣除道具 local itemConfig = ConfigDataManager.getTableValue("cfg_rep", "itemId", "id", configId) local itemArr = {} if itemConfig == "" then elseif string.contains(itemConfig, "|") then local tmpItemArr = string.split(itemConfig, "|") for i,tmpItemStr in ipairs(tmpItemArr) do local tmpItem = string.split(tmpItemStr, "#") itemArr[i] = tmpItem end else local tmpItem = string.split(itemConfig, "#") itemArr[1] = tmpItem end for i = 1, #itemArr do local itemData = itemArr[#itemArr - i + 1] local result = removeitemfrombag(actor, itemData[1], itemData[2], 0, 9999, '恶魔广场') if result then break end end -- local itemMap = string.toIntIntMap(itemConfig, "#", "|") -- for key, value in pairs(itemMap) do -- removeitemfrombag(actor, key, value, 0, 9999, '恶魔广场') -- end end -- @description 玩家传送进副本 -- @param 玩家对象;地图id;x坐标;y坐标;cfg_rep的id -- @return function DevilSquare.PlayerEnterDevilSquare(actor, mapId, x, y, configId) -- 扣除次数 local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId) local leftTimes = getleftcountofactivity(actor, activityId) -- 判断次数是否足够,足够则扣次数,不够则扣除背包的活动次数道具 if leftTimes > 0 then reduceactivitytimes(actor, activityId) else local result = removeitemfrombag(actor, 50010115, 1, 0, 9999, '恶魔广场') if not result then return end end -- 扣除道具 local itemConfig = ConfigDataManager.getTableValue("cfg_rep", "itemId", "id", configId) local itemArr = {} if itemConfig == "" then elseif string.contains(itemConfig, "|") then local tmpItemArr = string.split(itemConfig, "|") for i,tmpItemStr in ipairs(tmpItemArr) do local tmpItem = string.split(tmpItemStr, "#") itemArr[i] = tmpItem end else local tmpItem = string.split(itemConfig, "#") itemArr[1] = tmpItem end for i = 1, #itemArr do local itemData = itemArr[#itemArr - i + 1] local result = removeitemfrombag(actor, itemData[1], itemData[2], 0, 9999, '恶魔广场') if result then break end end -- local itemMap = string.toIntIntMap(itemConfig, "#", "|") -- for key, value in pairs(itemMap) do -- removeitemfrombag(actor, key, value, 0, 9999, '恶魔广场') -- end enterduplicate(actor, mapId, x, y) end --恶魔广场阶段更新 function DevilSquare.DevilSquareStateUpdate(system, id, state, nextStateStartTime, configId) if state == DuplicateState.PREPARE then --准备阶段,等待满人开启,发给客户端下次开启时间 -- 初始化副本数据 DevilSquare.InitDupDataDevilSquare(id) elseif state == DuplicateState.FIGHT then --战斗阶段,刷怪 local monsterId = ConfigDataManager.getTableValue("cfg_rep", "monster", "id", configId) local durationTime = ConfigDataManager.getTableValue("cfg_rep", "continuous", "id", configId) durationTime = tonumber(durationTime) setenvirvar(id, DuplicateVarConst.DEVIL_SQUARE_STATE, 1) setenvirvar(id, DuplicateVarConst.DEVIL_SQUARE_STATE_NEXT_TIME, nextStateStartTime - durationTime * 1000) DevilSquare.GenMonsterDevilSquare(id, monsterId) DevilSquare.ResAllPlayCurrencyStateInfo(id) DevilSquare.ResAllPlayDupTaskUpdate(id) -- 做定时器刷新,监听波次状态 local waveTime = ConfigDataManager.getTableValue("cfg_repMonster", "time", "id", monsterId) waveTime = tonumber(waveTime) local now = getbaseinfo("now") local delay = nextStateStartTime - durationTime * 1000 + waveTime * 1000 - now setenvirontimer(id, delay, 0, 1, "devilsquarestatetimeupdate", id) end end function devilsquarestatetimeupdate(system, mapId) local nextStartTime = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_NEXT_TIME) or 0 nextStartTime = tonumber(nextStartTime) if nextStartTime <= 0 then return end local genMonCfgId = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG) or 0 local waveTime = ConfigDataManager.getTableValue("cfg_repMonster", "time", "id", genMonCfgId) waveTime = tonumber(waveTime) local curState = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE) or 1 local now = getbaseinfo("now") if now >= nextStartTime + waveTime * 1000 * curState then --生成下一波怪 local nextGenMonCfgId = ConfigDataManager.getTableValue("cfg_repMonster", "nextID", "id", genMonCfgId) DevilSquare.GenMonsterDevilSquare(mapId, nextGenMonCfgId) curState = curState + 1 setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE, curState) setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT, 0) DevilSquare.ResAllPlayDupTaskUpdate(mapId) end setenvirontimer(mapId, nextStartTime + waveTime * 1000 * curState - now, 0, 1, "devilSquareStateTimeUpdate", mapId) end -- @description 玩家进入副本后 -- @param 玩家对象;地图id;副本阶段;下一阶段开始时间戳;配置id(cfg_rep的id) -- @return function DevilSquare.AfterPlayerEnterDevilSquare(actor, mapId, state, nextStateStartTime, configId) local dupInfo = getduplicate(mapId) local players = dupInfo["players"] local playerDupInfo = getplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO) -- 是否是新进入的副本 local newEnter = false if playerDupInfo == nil or playerDupInfo == "" then newEnter = true else local lastMapId = playerDupInfo[1] if mapId ~= lastMapId then newEnter = true end end if newEnter == true then -- 进入新的副本,初始化玩家变量 playerDupInfo = { mapId, configId } setplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO, playerDupInfo) setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT, 0) setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP, 0) -- 如果是新副本,则添加定时器,如果准备阶段走完,则直接开启副本 local now = getbaseinfo("now") setenvirontimer(mapId, nextStateStartTime - now, 0, 1, "devilsquarebattlestart", mapId) print("DevilSquare.AfterPlayerEnterDevilSquare 新副本,开启定时器,准备时间到后开启战斗", nextStateStartTime - now) end local maxCount = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.PREPARE_MAX_COUNT) --阶段信息 DevilSquare.ResCurrencyStateInfo(actor, mapId) -- 如果是准备阶段,判断人满立即开启 if state == DuplicateState.PREPARE then local playerCount = #players if playerCount >= tonumber(maxCount) then setduplicatestate(mapId, SetDuplicateStateConst.TO_FIGHT) setenvirontimer(mapId, 0.1, 0, 1, "devilsquarebattlestateupdate", mapId) return end elseif state == DuplicateState.FIGHT then DevilSquare.ResDupTaskUpdate(actor, mapId) end end function devilsquarebattlestateupdate(system, mapId) DevilSquare.ResAllPlayCurrencyStateInfo(mapId) end function devilsquarebattlestart(system, mapId) setduplicatestate(mapId, SetDuplicateStateConst.TO_FIGHT) end -- @description 初始化副本数据 -- @param 副本地图唯一id -- @return function DevilSquare.InitDupDataDevilSquare(mapId) --当前波次怪物击杀数量 setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT, 0) end -- @description 刷怪 -- @param 地图唯一id;刷怪表id -- @return function DevilSquare.GenMonsterDevilSquare(mapId, genMonCfgId) --战斗阶段才可以刷怪 local dupInfo = getduplicate(mapId) if dupInfo["state"] ~= DuplicateState.FIGHT then return end -- info("恶魔广场清空怪物开始") --清空当前地图怪物 local monsterInfoList = mapbossinfo(mapId) for key, monInfo in pairs(monsterInfoList) do local monId = monInfo["id"] local monster = getactor(monId, mapId) removemapobject(monster) end -- info("恶魔广场清空怪物结束") --储存当前刷怪配置 setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG, genMonCfgId) DuplicateCommon.DupGenMonsterCommon(mapId, genMonCfgId) end -- @description 击杀怪物 -- @param 归属者;默认掉落经验;怪物配置id -- @return 经验值 function DevilSquare.KillMonterInDevilSquare(actor, mapId, exp, monCfgId) -- 当前波次击杀的怪物 local oldCount = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT) or 0 local newCount = oldCount + 1 local genMonCfgId = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG) or 0 local totalCount = ConfigDataManager.getTableValue("cfg_repMonster", "kill", "id", genMonCfgId) totalCount = tonumber(totalCount) local now = getbaseinfo("now") if totalCount > 0 and newCount >= totalCount then newCount = 0 --生成下一波怪 local nextGenMonCfgId = ConfigDataManager.getTableValue("cfg_repMonster", "nextID", "id", genMonCfgId) DevilSquare.GenMonsterDevilSquare(mapId, nextGenMonCfgId) local oldState = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE) local newState = oldState + 1 setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE, newState) local waveTime = ConfigDataManager.getTableValue("cfg_repMonster", "time", "id", genMonCfgId) setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_NEXT_TIME, now + waveTime * 1000) end setenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT, newCount) -- 玩家击杀数量 local killCount = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT) if killCount == nil or killCount <= 0 then killCount = 0 end killCount = killCount + 1 setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT, killCount) end function DevilSquare.AddExp(actor, mapId, exp) -- 玩家杀怪经验 -- local killExp = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP) -- if killExp == nil or killExp <= 0 then -- killExp = 0 -- end -- killExp = killExp + exp -- setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP, killExp) -- DevilSquare.ResAllPlayDupTaskUpdate(mapId) -- OpenServerCompetition.expCal(actor, exp) end -- @description 玩家副本结算 -- @param 玩家对象; -- @return function DevilSquare.PlayerSettleMentDevilSquare(actor) -- 击杀怪物 local killCount = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT) -- 获得经验 local killExp = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP) local playerDupInfo = getplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO) local configId = playerDupInfo[2] local score, scoreExp = DevilSquare.CalcuScoreAndExp(configId) local totalScoreExp = killCount * score * scoreExp -- 经验加成 totalScoreExp = Player.calculExpByAddRate(actor, totalScoreExp) -- 这里发放积分经验 -- additemtobag(actor, ItemConfigId.EXP, totalScoreExp, 0, 9999, '恶魔广场') -- 活动剩余次数 local leftCount = getleftcountofactivity(actor, DuplicateType.DEVIL_SQUARE) -- 发回给客户端 local response = {} response["configId"] = configId --配置表id response["kill"] = killCount --击杀怪物数量 response["killExp"] = killExp --击杀怪物掉落的经验 response["scoreExp"] = totalScoreExp --积分经验 response["leftCount"] = leftCount --剩余次数 sendluamsg(actor, LuaMessageIdToClient.RES_DEVIL_SQUARE_SETTLEMENT, response) end -- @description 计算配置的积分及积分经验 -- @param cfg_rep的id -- @return 积分,积分经验 function DevilSquare.CalcuScoreAndExp(configId) local repLevel = ConfigDataManager.getTableValue("cfg_rep", "repLevel", "id", configId) repLevel = tonumber(repLevel) local configStr = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.DEVIL_SQUARE_SCORE_EXP) local configList = string.split(configStr, "|") local score local scoreExp for index, value in ipairs(configList) do local valueList = string.split(value, "#") local configLevel = tonumber(valueList[1]) if repLevel == configLevel then score = tonumber(valueList[2]) scoreExp = tonumber(valueList[3]) return score, scoreExp end end return 0, 0 end -- @description 玩家进入任意地图事件 -- @param 玩家对象;上一个地图配置id;当前地图配置id -- @return function DevilSquare.EnterAllMapDS(actor, lastMapCfgId, mapCfgId) -- 判断发送副本结算 -- local dupInfo = getplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO) -- if dupInfo == nil or dupInfo == "" then -- return -- end -- local devilSquareId = dupInfo[1] -- local mapId = getbaseinfo(actor, "unimapid") -- local mapInfo = getmapinfobyid(mapId) -- local isDup = mapInfo["isdup"] -- if isDup == true and devilSquareId ~= mapId then -- error("恶魔广场有未结算的奖励") -- DevilSquare.ClearPlayerDevilSquareDef(actor) -- return -- end -- if devilSquareId ~= mapId then -- -- 结算 -- gameDebug.debug(LogManager.TriggerByType, actor, LogOpType.B_AND_D_CHALLENGE) -- DevilSquare.PlayerSettleMentDevilSquare(actor) -- end end -- @description 客户端请求领取奖励 -- @param 玩家对象;领取倍数 -- @return function DevilSquare.ReqReciveRewardDevilSquare(actor, multipleCount) -- multipleCount = tonumber(multipleCount) -- local dupInfo = getplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO) -- if dupInfo == nil or dupInfo == "" then -- return -- end -- -- 经验 -- local killExp = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP) -- local killCount = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT) -- local configId = dupInfo[2] -- local score, scoreExp = DevilSquare.CalcuScoreAndExp(configId) -- local totalScoreExp = killCount * score * scoreExp -- totalScoreExp = Player.calculExpByAddRate(actor, totalScoreExp) -- -- 副本进度任务刷新 -- DuplicateCommon.FinishDupActivity(actor, configId) -- if multipleCount <= 1 then -- -- 清空角色副本信息 -- DevilSquare.ClearPlayerDevilSquareDef(actor) -- return -- end -- local cfgString = ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.DEVIL_SQUARE_MULTIPLE_REWARD) -- local cfgList = string.split(cfgString, "|") -- for index, value in ipairs(cfgList) do -- local valueList = string.split(value, "#") -- if multipleCount == tonumber(valueList[1]) then -- local costItemId = tonumber(valueList[2]) -- local costItemCount = tonumber(valueList[3]) -- local costActivityCount = tonumber(valueList[4]) -- local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId) -- local leftCount = getleftcountofactivity(actor, activityId) -- if leftCount < costActivityCount then -- --tipinfo(actor, "次数不足") -- return -- end -- local ownCount = getbagitemcountbyid(actor, costItemId) -- if ownCount < costItemCount then -- --tipinfo(actor, "扣除道具不足") -- return -- end -- -- 扣除次数和道具 -- reduceactivitytimes(actor, activityId, costActivityCount) -- removeitemfrombag(actor, costItemId, costItemCount, 0, 9999, '恶魔广场') -- -- 发放奖励 -- local totalExp = killExp * (multipleCount - 1) + totalScoreExp * (multipleCount - 1) -- additemtobag(actor, ItemConfigId.EXP, totalExp, 0, 9999, '恶魔广场') -- -- 清空角色副本信息 -- DevilSquare.ClearPlayerDevilSquareDef(actor) -- end -- end end -- @description 清除玩家在恶魔广场副本中的变量 -- @param 玩家对象 -- @return function DevilSquare.ClearPlayerDevilSquareDef(actor) setplaydef(actor, DevilSquarePlayerConst.DEVIL_SQUARE_MAP_INFO, "") setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT, 0) setplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_EXP, 0) end -- @description 响应给客户端当前阶段 -- @param 玩家对象;地图id -- @return function DevilSquare.ResCurrencyStateInfo(actor, mapId) local dupInfo = getduplicate(mapId) local state = dupInfo["state"] local configId = dupInfo["dupcfgid"] local nextStateStartTime = dupInfo["nextstatetime"] sendluamsg(actor, LuaMessageIdToClient.DEVIL_SQUARE_STATE, { state, tostring(nextStateStartTime), configId }) end -- @description 通知地图所有玩家更新当前阶段 -- @param 地图id -- @return function DevilSquare.ResAllPlayCurrencyStateInfo(mapId) local dupInfo = getduplicate(mapId) local players = dupInfo["players"] for index, actor in ipairs(players) do DevilSquare.ResCurrencyStateInfo(actor, mapId) end end -- @description 立即开启战斗 -- @param 玩家对象;请求参数 -- @return function DevilSquare.ChangeToFight(actor, msgData) local mapId = getbaseinfo(actor, "unimapid") setduplicatestate(mapId, SetDuplicateStateConst.TO_FIGHT) end -- @description 副本任务更新响应 -- @param 玩家对象;副本id -- @return function DevilSquare.ResDupTaskUpdate(actor, mapId) local dupInfo = getduplicate(mapId) local configId = dupInfo["dupcfgid"] --波次 local wave = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE) or 1 --击杀数量 local count = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT) or 0 --任务总数量 local genMonCfgId = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG) or 0 local totalCount = ConfigDataManager.getTableValue("cfg_repMonster", "kill", "id", genMonCfgId) local killCount = getplaydef(actor, DevilSquarePlayerConst.KILL_MONSTER_COUNT) --通关奖励 local score, scoreExp = DevilSquare.CalcuScoreAndExp(configId) local totalScoreExp = killCount * score * scoreExp totalScoreExp = Player.calculExpByAddRate(actor, totalScoreExp) --击杀怪物积分 local killScore = killCount * score local response = {} response["wave"] = wave response["nowCount"] = count response["totalCount"] = totalCount response["rewardCount"] = totalScoreExp response["score"] = killScore sendluamsg(actor, LuaMessageIdToClient.RES_DEVIL_SQUARE_TASK, response) end -- @description 通知地图所有玩家更新当前任务 -- @param 副本id -- @return function DevilSquare.ResAllPlayDupTaskUpdate(mapId) local dupInfo = getduplicate(mapId) local players = dupInfo["players"] for index, actor in ipairs(players) do DevilSquare.ResDupTaskUpdate(actor, mapId) end end