--恶魔广场副本 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 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) reduceactivitytimes(actor, activityId) -- 扣除道具 local itemConfig = ConfigDataManager.getTableValue("cfg_rep", "itemId", "id", configId) 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) setenvirvar(id, DuplicateVarConst.DEVIL_SQUARE_STATE, 1) DevilSquare.GenMonsterDevilSquare(id, monsterId) DevilSquare.ResAllPlayCurrencyStateInfo(id) DevilSquare.ResAllPlayDupTaskUpdate(id) end 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) 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) return end elseif state == DuplicateState.FIGHT then DevilSquare.ResDupTaskUpdate(actor, mapId) end 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 --储存当前刷怪配置 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) local newCount = oldCount + 1 local genMonCfgId = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG) local totalCount = ConfigDataManager.getTableValue("cfg_repMonster", "kill", "id", genMonCfgId) if newCount >= tonumber(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) 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) -- 玩家杀怪经验 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 -- 这里发放积分经验 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 -- 副本进度任务刷新 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) --击杀数量 local count = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_STATE_KILL_COUNT) --任务总数量 local genMonCfgId = getenvirvar(mapId, DuplicateVarConst.DEVIL_SQUARE_MONSTER_GEN_CONFIG) 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 --击杀怪物积分 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