DuplicateCommon_1.lua 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. --[[ 副本通用方法尽量走这里,可复用。
  2. 接口:
  3. 1、客户端请求进入副本 DuplicateCommon.ReqEnterDupLicate
  4. 2、客户端请求退出副本 DuplicateCommon.ReqQuitDuplicate
  5. 3、通用创建副本地图 DuplicateCommon.CreateDupMapCommon
  6. 4、多人副本,找一个还在准备阶段的空副本 DuplicateCommon.FindEnterableDupCommon
  7. 5、获取进入副本的x,y坐标 DuplicateCommon.GetEnterPointXYCommon
  8. 6、副本刷怪 DuplicateCommon.DupGenMonsterCommon
  9. 7、创建副本任务通用信息 DuplicateCommon.GenDupTaskInfoCommon
  10. 8、请求修改副本状态 DuplicateCommon.ReqChangeDupState
  11. 9、获取活动剩余次数 DuplicateCommon.ReqGetActivityLeftCount
  12. 10、副本组队通用接口,调用DuplicateCommon.CallTeamMembersPrepare;在DuplicateCommon.DoTeamEnterDup写自己的组队拉人进入逻辑
  13. 事件: 事件转移到QFunction-0.lua文件中了
  14. 1、副本阶段更新 dupstateupdate
  15. 2、怪物死亡掉落经验事件 monsterdieexp
  16. 3、玩家进入副本事件 afterenterduplicate
  17. 4、玩家退出副本事件 afterquitduplicate
  18. 5、玩家进入地图事件(可以是普通地图也可以是副本) entermap
  19. 6、地图怪物死亡事件(可以是普通地图也可以是副本) mapmonsterdie
  20. 9、玩家进入视野 PlayerEnterView
  21. 通用协议:
  22. 请求:
  23. REQ_ENTER_DUPLICATE = 2000021, -- 请求进入副本
  24. REQ_CHANGE_DUPLICATE_STATE = 2000024, -- 修改副本状态
  25. REQ_QUIT_DUPLICATE = 2000034, -- 请求退出副本
  26. 响应:
  27. RES_QUIT_DUPLICATE = 1000039, -- 退出副本回包
  28. ]]
  29. DuplicateCommon = {}
  30. local this = {}
  31. -- @description 请求获取活动剩余次数
  32. -- @param 玩家对象;活动id
  33. -- @return
  34. function DuplicateCommon.ReqGetActivityLeftCount(actor, activityId)
  35. local leftCount = getleftcountofactivity(actor, activityId)
  36. if leftCount < 0 then
  37. leftCount = 0
  38. end
  39. sendluamsg(actor, LuaMessageIdToClient.RES_GET_ACTIVITY_COUNT, { activityId, leftCount })
  40. end
  41. -- @description 客户端请求进入副本
  42. -- @param 玩家对象;cfg_rep的id
  43. -- @return
  44. function DuplicateCommon.ReqEnterDupLicate(actor, configId)
  45. -- 判断活动是否开启
  46. local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  47. gameDebug.assertNil(activityId, "活动", configId, "配置不存在!")
  48. if activityId ~= nil and activityId ~= "" and tonumber(activityId) ~= DuplicateType.ITEM_BOSS then
  49. local activityInfo = getactivityinfo(activityId)
  50. if activityInfo["open"] == nil or activityInfo["open"] == false then
  51. noticeTip.noticeinfo(actor, StringIdConst.TEXT390)
  52. return
  53. end
  54. end
  55. -- 开服天数判断
  56. local startDay = ConfigDataManager.getTableValue("cfg_rep", "startDay", "id", configId)
  57. startDay = tonumber(startDay)
  58. if startDay ~= nil and startDay ~= "" then
  59. local serverOpenDays = tonumber(getserveropendays(actor))
  60. if serverOpenDays < startDay then
  61. noticeTip.noticeinfo(actor, StringIdConst.TEXT391)
  62. return
  63. end
  64. end
  65. -- 组队限制
  66. local teamType = ConfigDataManager.getTableValue("cfg_rep", "team", "id", configId)
  67. teamType = tonumber(teamType)
  68. local teamId = getbaseinfo(actor, "teamid")
  69. if teamType == DupTeamType.NONE then
  70. --不限制单人或者组队
  71. if teamId ~= 0 then
  72. local check, tip = this.TeamEnterCheck(actor)
  73. if check == false then
  74. tipinfo(actor, tip)
  75. return
  76. end
  77. end
  78. elseif teamType == DupTeamType.PERSONAL then
  79. --限制单人
  80. if teamId ~= 0 then
  81. noticeTip.noticeinfo(actor, StringIdConst.TEXT392)
  82. return
  83. end
  84. elseif teamType == DupTeamType.TEAM then
  85. --限制组队
  86. local check, tip = this.TeamEnterCheck(actor)
  87. if check == false then
  88. tipinfo(actor, tip)
  89. return
  90. end
  91. elseif teamType == DupTeamType.UNION then
  92. --TODO:组队成员必须是战盟成员
  93. end
  94. local dupType = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  95. dupType = tonumber(dupType)
  96. -- 当前角色在秘境副本中不能进入其他副本
  97. if SecretRealm.isSecretRealmMap(getbaseinfo(actor, "mapid")) then
  98. noticeTip.noticeinfo(actor, StringIdConst.DUPLICATE_CAN_NOT_TRANSMIT)
  99. return
  100. end
  101. if dupType == DuplicateType.DEVIL_SQUARE then
  102. -- 进入恶魔广场
  103. DevilSquare.ReqEnterDevilSquare(actor, configId)
  104. elseif dupType == DuplicateType.BLOODY_CASTLE then
  105. --进入血色城堡
  106. BloodyCastle.ReqEnterBloodyCastle(actor, configId)
  107. elseif dupType == DuplicateType.BRAVE_TEST then
  108. BraveTest.ReqEnterBraveTest(actor, configId)
  109. elseif dupType == DuplicateType.RED_FORTRESS then
  110. RedFortress.ReqEnterFortress(actor, configId)
  111. elseif dupType == DuplicateType.PRIVILEGE_BOSS then
  112. PrivilegeBoss.ReqEnterPrivilegeBoss(actor, configId)
  113. elseif dupType == DuplicateType.WOLF_SOUL then
  114. WolfSoul.ReqEnterWolfSoul(actor)
  115. elseif dupType == DuplicateType.COMBO_TEST then
  116. ComboTest.ReqEnterComboTest(actor, configId)
  117. elseif dupType == DuplicateType.BIG_SECRET_REALM then
  118. BigSecretRealm.ReqEnterBigSecretRealm(actor, configId)
  119. elseif dupType == DuplicateType.ROLAND_SEIGE then
  120. RolandSeige.ReqEnterDupLicate(actor)
  121. elseif dupType == DuplicateType.ITEM_BOSS then
  122. --进入道具boss
  123. ItemBoss.ReqEnterItemBoss(actor, configId)
  124. elseif dupType == DuplicateType.WORLD_BOSS then
  125. WorldBoss.ReqEnterWorldBoss(actor, configId)
  126. end
  127. end
  128. -- @description 组队限制
  129. -- @param 玩家对象
  130. -- @return true | false ; 提示内容
  131. function this.TeamEnterCheck(actor)
  132. local teamId = getbaseinfo(actor, "teamid")
  133. if teamId == 0 then
  134. return false, "请先创建或加入一个队伍!"
  135. end
  136. local selfId = getbaseinfo(actor, "rid")
  137. local teamInfo = getteaminfo(actor, teamId)
  138. local leaderId = teamInfo["leaderid"]
  139. if tostring(selfId) ~= tostring(leaderId) then
  140. return false, "您不是队长!"
  141. end
  142. local members = teamInfo["allteammemberinfo"]
  143. for index, memberInfo in ipairs(members) do
  144. local memberId = memberInfo["rid"]
  145. local memberActor = getactor(actor, memberId)
  146. local inDup = this.IsInDuplicate(memberActor)
  147. if inDup then
  148. return false, "队员正在副本中!等待队员退出副本!"
  149. end
  150. end
  151. return true, ""
  152. end
  153. -- @description 是否在副本中
  154. -- @param actor
  155. -- @return true-在
  156. function DuplicateCommon.IsInDuplicate(actor)
  157. return this.IsInDuplicate(actor)
  158. end
  159. function this.IsInDuplicate(actor)
  160. local mapId = getbaseinfo(actor, "unimapid")
  161. local mapInfo = getmapinfobyid(mapId)
  162. if mapInfo["isdup"] == true then
  163. return true
  164. else
  165. return false
  166. end
  167. end
  168. -- @description 回蓝回血
  169. -- @param 玩家对象
  170. -- @return
  171. function DuplicateCommon.RecoverHPMP(actor)
  172. --设置血量
  173. local roleInfo = getplayermaininfo(actor)
  174. local maxHp = roleInfo["maxhp"]
  175. sethp(actor, maxHp)
  176. --设置蓝量
  177. local maxMap = roleInfo["maxmp"]
  178. setmp(actor, maxMap)
  179. end
  180. -- @description 通用进入限制条件检查
  181. -- @param 玩家对象,cfg_rep的id
  182. -- @return EnterLimitResultConst
  183. function DuplicateCommon.CheckEnterConditonCommon(actor, configId)
  184. local playerLevel = tonumber(getbaseinfo(actor, "level"))
  185. local levelConfig = ConfigDataManager.getTableValue("cfg_rep", "level", "id", configId)
  186. if not string.isNullOrEmpty(levelConfig) then
  187. local levelList = string.split(levelConfig, "#")
  188. local minLevel = tonumber(levelList[1])
  189. local maxLevel = tonumber(levelList[2])
  190. if playerLevel < minLevel or playerLevel > maxLevel then
  191. return EnterLimitResultConst.LEVEL
  192. end
  193. end
  194. local activityId = tonumber(ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId))
  195. if activityId == nil or activityId <= 0 then
  196. gameDebug.assertPrintTrace(false, actor:toString() .. "进入副本检查, 活动id错误,副本cfgId: " .. configId)
  197. return false
  198. end
  199. if activityId ~= DuplicateType.ITEM_BOSS then
  200. local leftCount = getleftcountofactivity(actor, activityId)
  201. if leftCount <= 0 then
  202. if activityId == DuplicateType.DEVIL_SQUARE then
  203. local itemNum = getbagitemcountbyid(actor, 50010115)
  204. if itemNum <= 0 then
  205. return EnterLimitResultConst.COUNT
  206. end
  207. else
  208. return EnterLimitResultConst.COUNT
  209. end
  210. end
  211. end
  212. local itemString = ConfigDataManager.getTableValue("cfg_rep", "itemId", "id", configId)
  213. local itemTable = string.toIntIntMap(itemString, "#", "|")
  214. local hasTicket = false
  215. for itemId, count in pairs(itemTable) do
  216. itemId = tonumber(itemId)
  217. count = tonumber(count)
  218. local ownCount = getbagitemcountbyid(actor, itemId)
  219. if ownCount >= count then
  220. hasTicket = true
  221. end
  222. end
  223. if not hasTicket then
  224. return EnterLimitResultConst.ITEM
  225. end
  226. return EnterLimitResultConst.ALLOW
  227. end
  228. -- @description 通用创建副本地图
  229. -- @param 玩家对象;cfg_rep的id;是否可以离线挂机
  230. -- @return 副本地图唯一id
  231. function DuplicateCommon.CreateDupMapCommon(actor, configId, canHook)
  232. local dupConfigMap = ConfigDataManager.getById("cfg_rep", configId)
  233. local mapCfgId = dupConfigMap.mapid
  234. local type = dupConfigMap.type
  235. local prepareTime = dupConfigMap.preparetime
  236. local continuous = dupConfigMap.continuous
  237. local save = dupConfigMap.save
  238. local mapId = createduplicate(actor, mapCfgId, type, type, configId, prepareTime, continuous, save, canHook)
  239. return mapId
  240. end
  241. -- @description 多人副本,找一个还在准备阶段的空副本
  242. -- @param cfg_rep的id;空余人数
  243. -- @return 副本地图唯一id
  244. function DuplicateCommon.FindEnterableDupCommon(configId, needSize)
  245. local mapId = 0
  246. local maxSize = ConfigDataManager.getTableValue("cfg_rep", "warNumMax", "id", configId)
  247. local type = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  248. local existDupList = getduplicatelist(type)
  249. for index, dupInfo in ipairs(existDupList) do
  250. local players = dupInfo["players"]
  251. local state = dupInfo["state"]
  252. local dupConfig = dupInfo["dupcfgid"]
  253. local leftSize = tonumber(maxSize) - #players
  254. if state == DuplicateState.PREPARE and leftSize >= needSize and tonumber(dupConfig) == tonumber(configId) then
  255. mapId = dupInfo["id"]
  256. break
  257. end
  258. end
  259. return mapId
  260. end
  261. -- @description 获取进入副本的x,y坐标
  262. -- @param configId——cfg_rep的id
  263. -- @return
  264. function DuplicateCommon.GetEnterPointXYCommon(configId)
  265. local mapMoveString = ConfigDataManager.getTableValue("cfg_rep", "mapMove", "id", configId)
  266. local mapMoveIds = string.split(mapMoveString, "#")
  267. local randomIndex = math.random(#mapMoveIds)
  268. local randomId = mapMoveIds[randomIndex]
  269. local x = ConfigDataManager.getTableValue("cfg_mapMove", "mapX", "id", randomId)
  270. local y = ConfigDataManager.getTableValue("cfg_mapMove", "mapY", "id", randomId)
  271. return tonumber(x), tonumber(y)
  272. end
  273. -- @description 通用副本刷怪
  274. -- @param 地图唯一id;刷怪表id(cfg_repMonster)
  275. -- @return
  276. function DuplicateCommon.DupGenMonsterCommon(mapId, configId)
  277. local monsterStr = ConfigDataManager.getTableValue("cfg_repMonster", "monster", "id", configId)
  278. local monsterStrList = string.split(monsterStr, "|")
  279. local monsterActors = {}
  280. for _, value in ipairs(monsterStrList) do
  281. local params = string.split(value, "#")
  282. local monId = params[1]
  283. local count = params[2]
  284. local x = params[3]
  285. local y = params[4]
  286. local range = params[5]
  287. local monsterActor = mongen(mapId, x, y, range, monId, count)
  288. table.insertArray(monsterActors, monsterActor)
  289. --monsterActors[index] = monsterActor
  290. end
  291. return monsterActors
  292. end
  293. -- @description 创建副本任务通用信息
  294. -- @param 任务id
  295. -- @return 任务信息
  296. function DuplicateCommon.GenDupTaskInfoCommon(taskId)
  297. local ret
  298. local taskType = ConfigDataManager.getTableValue("cfg_repTask", "type", "id", taskId)
  299. taskType = tonumber(taskType)
  300. local param = ConfigDataManager.getTableValue("cfg_repTask", "param", "id", taskId)
  301. if taskType == DuplicateTaskType.KILL_MONSTER_COUNT then
  302. ret = { taskId, taskType, tonumber(param), 0 }
  303. elseif taskType == DuplicateTaskType.KILL_TARGET_MONSTER then
  304. local split = string.split(param, "#")
  305. local targetId = tonumber(split[1])
  306. local count = tonumber(split[2])
  307. ret = { taskId, taskType, count, 0, targetId }
  308. elseif taskType == DuplicateTaskType.PICK_TARGET_ITEM then
  309. ret = { taskId, taskType, 1, 0 }
  310. elseif taskType == DuplicateTaskType.ROLAND_SEIGE_OCCUPY then
  311. ret = { taskId, taskType, 1, 0 }
  312. end
  313. return ret
  314. end
  315. -- @description 请求退出副本
  316. -- @param 玩家对象
  317. -- @return
  318. function DuplicateCommon.ReqQuitDuplicate(actor, msgData)
  319. if msgData == nil then
  320. quitduplicate(actor)
  321. return
  322. end
  323. local type = ConfigDataManager.getTableValue("cfg_rep", "type", "id", msgData)
  324. if tonumber(type) == DuplicateType.COMBO_TEST then
  325. ComboTest.quitDuplicate(actor, msgData)
  326. elseif tonumber(type) == DuplicateType.BIG_SECRET_REALM then
  327. BigSecretRealm.quitBigSecretRealm(actor, msgData)
  328. end
  329. quitduplicate(actor)
  330. end
  331. -- @description 请求修改副本状态
  332. -- @param 玩家对象; 下一阶段
  333. -- @return
  334. function DuplicateCommon.ReqChangeDupState(actor, state)
  335. local mapId = getbaseinfo(actor, "unimapid")
  336. local mapInfo = getmapinfobyid(mapId)
  337. if mapInfo["isdup"] == false then
  338. return
  339. end
  340. setduplicatestate(mapId, state)
  341. end
  342. -- @description 玩家进入视野
  343. -- @param 玩家对象;进入视野的玩家对象
  344. -- @return
  345. function DuplicateCommon.PlayerEnterView(actor, target)
  346. local mapId = getbaseinfo(actor, "unimapid")
  347. local dupInfo = getduplicate(mapId)
  348. if dupInfo == false or dupInfo == nil then
  349. return
  350. end
  351. local dupType = dupInfo["type"]
  352. if dupType == DuplicateType.BLOODY_CASTLE then
  353. BloodyCastle.PlayerEnterView(actor, target, mapId)
  354. end
  355. end
  356. -- @description 副本组队准备
  357. -- @param 玩家对象;配置id
  358. -- @return
  359. function DuplicateCommon.CallTeamMembersPrepare(actor, configId)
  360. local teamId = getbaseinfo(actor, "teamid")
  361. local teamInfo = getteaminfo(actor, teamId)
  362. local members = teamInfo["allteammemberinfo"]
  363. for index, memberInfo in ipairs(members) do
  364. local memberId = memberInfo["rid"]
  365. local memberActor = getactor(actor, memberId)
  366. setplaydef(memberActor, PlayerDefKey.DUP_TEAM_BELONG, configId)
  367. setplaydef(memberActor, PlayerDefKey.DUP_TEAM_READY, false)
  368. end
  369. --队长默认准备
  370. setplaydef(actor, PlayerDefKey.DUP_TEAM_READY, true)
  371. DuplicateCommon.ResAllTeamPreparePanel(actor, configId)
  372. end
  373. -- @description 副本组队面板全体回包
  374. -- @param 玩家对象;配置id;除外的玩家id
  375. -- @return
  376. function DuplicateCommon.ResAllTeamPreparePanel(actor, configId, except)
  377. local teamId = getbaseinfo(actor, "teamid")
  378. local msg = DuplicateCommon.BuildTeamPrepareMsg(actor, teamId, configId)
  379. local teamInfo = getteaminfo(actor, teamId)
  380. local members = teamInfo["allteammemberinfo"]
  381. for index, memberInfo in ipairs(members) do
  382. -- todo 给客户端回包
  383. local memberId = memberInfo["rid"]
  384. if tostring(memberId) ~= tostring(except) then
  385. local memberActor = getactor(actor, memberId)
  386. sendluamsg(memberActor, LuaMessageIdToClient.RES_DUPLICATE_TEAM_INFO, msg)
  387. end
  388. end
  389. end
  390. -- @description 副本组队面板回包
  391. -- @param 玩家对象;配置id
  392. -- @return
  393. function DuplicateCommon.ResTeamPreparePanel(actor, configId)
  394. local teamId = getbaseinfo(actor, "teamid")
  395. local msg = DuplicateCommon.BuildTeamPrepareMsg(actor, teamId, configId)
  396. sendluamsg(actor, LuaMessageIdToClient.RES_DUPLICATE_TEAM_INFO, msg)
  397. end
  398. -- @descrip0tion 构建组队准备消息
  399. -- @param 玩家对象;队伍id
  400. -- @return 响应消息
  401. function DuplicateCommon.BuildTeamPrepareMsg(actor, teamId, configId)
  402. local msg = {}
  403. local teamInfo = getteaminfo(actor, teamId)
  404. local members = teamInfo["allteammemberinfo"]
  405. local memberList = {}
  406. for index, memberInfo in ipairs(members) do
  407. local innerData = {}
  408. local memberId = memberInfo["rid"]
  409. local memberActor = getactor(actor, memberId)
  410. --玩家名字
  411. local memberName = getrolefield(memberActor, "role.basic.name")
  412. local check = DuplicateCommon.CheckEnterConditonCommon(memberActor, configId)
  413. if check == EnterLimitResultConst.ALLOW then
  414. local ready = getplaydef(memberActor, PlayerDefKey.DUP_TEAM_READY)
  415. if ready ~= true then
  416. check = EnterLimitResultConst.REFUSE
  417. end
  418. end
  419. --玩家职业
  420. local career = getrolefield(memberActor, "role.basic.career.basecareer")
  421. innerData["rid"] = memberId
  422. innerData["name"] = memberName
  423. innerData["state"] = check
  424. innerData["career"] = career
  425. table.insert(memberList, innerData)
  426. end
  427. msg["members"] = memberList
  428. -- 副本配置id
  429. msg["configId"] = configId
  430. -- 队长id
  431. msg["leaderid"] = teamInfo["leaderid"]
  432. return msg
  433. end
  434. -- @description 修改副本组队状态
  435. -- @param 玩家对象;状态
  436. -- @return
  437. function DuplicateCommon.ChangeTeamPrepareState(actor, state)
  438. local configId = getplaydef(actor, PlayerDefKey.DUP_TEAM_BELONG)
  439. state = tonumber(state)
  440. local teamId = getbaseinfo(actor, "teamid")
  441. local name = getrolefield(actor, "role.basic.name")
  442. if state == DupTeamChangeState.READY then
  443. if DuplicateCommon.CheckEnterConditonCommon(actor, configId) ~= EnterLimitResultConst.ALLOW then
  444. return
  445. end
  446. setplaydef(actor, PlayerDefKey.DUP_TEAM_READY, true)
  447. DuplicateCommon.ResAllTeamPreparePanel(actor, configId)
  448. elseif state == DupTeamChangeState.REFUSE then
  449. setplaydef(actor, PlayerDefKey.DUP_TEAM_READY, false)
  450. DuplicateCommon.ResAllBreakDupTeam(actor, teamId)
  451. DuplicateCommon.ResTipsAllTeam(actor, teamId, name .. "取消进入副本")
  452. elseif state == DupTeamChangeState.BREAK then
  453. local selfId = getbaseinfo(actor, "rid")
  454. local teamInfo = getteaminfo(actor, teamId)
  455. local leaderId = teamInfo["leaderid"]
  456. if tostring(selfId) ~= tostring(leaderId) then
  457. gameDebug.assertPrintTrace(false, selfId .. "不是队长,解散副本组队!")
  458. return
  459. end
  460. DuplicateCommon.ResAllBreakDupTeam(actor, teamId)
  461. DuplicateCommon.ResTipsAllTeam(actor, teamId, name .. "取消进入副本")
  462. end
  463. end
  464. -- @description 副本队伍全体tips
  465. -- @param 玩家对象
  466. -- @return
  467. function DuplicateCommon.ResTipsAllTeam(actor, teamId, tip)
  468. local teamInfo = getteaminfo(actor, teamId)
  469. local members = teamInfo["allteammemberinfo"]
  470. for index, memberInfo in ipairs(members) do
  471. local memberId = memberInfo["rid"]
  472. local memberActor = getactor(actor, memberId)
  473. tipinfo(memberActor, tip)
  474. end
  475. end
  476. -- @description 副本队伍解散全体回包
  477. -- @param 玩家对象
  478. -- @return
  479. function DuplicateCommon.ResAllBreakDupTeam(actor, teamId)
  480. local teamInfo = getteaminfo(actor, teamId)
  481. local members = teamInfo["allteammemberinfo"]
  482. for index, memberInfo in ipairs(members) do
  483. local memberId = memberInfo["rid"]
  484. local memberActor = getactor(actor, memberId)
  485. DuplicateCommon.ResBreakDupTeam(memberActor)
  486. end
  487. end
  488. -- @description 副本队伍解散回包
  489. -- @param 玩家对象
  490. -- @return
  491. function DuplicateCommon.ResBreakDupTeam(actor)
  492. setplaydef(actor, PlayerDefKey.DUP_TEAM_READY, false)
  493. setplaydef(actor, PlayerDefKey.DUP_TEAM_BELONG, 0)
  494. sendluamsg(actor, LuaMessageIdToClient.RES_BREAK_DUPLICATE_TEAM, nil)
  495. end
  496. -- @description 倒计时结束,队长拉人进入
  497. -- @param 玩家对象
  498. -- @return
  499. function DuplicateCommon.DoTeamEnterDup(actor)
  500. local configId = getplaydef(actor, PlayerDefKey.DUP_TEAM_BELONG)
  501. if configId <= 0 or configId == nil then
  502. return
  503. end
  504. local teamId = getbaseinfo(actor, "teamid")
  505. local selfId = getbaseinfo(actor, "rid")
  506. local teamInfo = getteaminfo(actor, teamId)
  507. local leaderId = teamInfo["leaderid"]
  508. if tostring(selfId) ~= tostring(leaderId) then
  509. gameDebug.assertPrintTrace(false, selfId .. "不是队长,组队进入副本!")
  510. return
  511. end
  512. local members = teamInfo["allteammemberinfo"]
  513. for index, memberInfo in ipairs(members) do
  514. local memberId = memberInfo["rid"]
  515. local memberActor = getactor(actor, memberId)
  516. local name = getrolefield(memberActor, "role.basic.name")
  517. local ready = getplaydef(memberActor, PlayerDefKey.DUP_TEAM_READY)
  518. if ready ~= true then
  519. DuplicateCommon.ResTipsAllTeam(actor, teamId, name .. "未准备")
  520. return
  521. end
  522. end
  523. local dupType = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  524. dupType = tonumber(dupType)
  525. if dupType == DuplicateType.DEVIL_SQUARE then
  526. DevilSquare.DoTeamEnter(actor, teamId, configId)
  527. elseif dupType == DuplicateType.BLOODY_CASTLE then
  528. --进入血色城堡
  529. BloodyCastle.DoTeamEnter(actor, teamId, configId)
  530. elseif dupType == DuplicateType.ITEM_BOSS then
  531. --进入道具boss
  532. ItemBoss.DoTeamEnter(actor, teamId, configId)
  533. end
  534. end
  535. ---根据地图信息获取怪物数量
  536. ---@param actor 玩家对象
  537. ---@param msgData 消息对象 mapCfgId:地图configId、line:地图线路、monsterCfgId:怪物configId、state:怪物状态(1:未死亡,0:所有)
  538. function DuplicateCommon.getmonstercountbymap(actor, msgData)
  539. local mapCfgId = msgData.mapCfgId
  540. if not mapCfgId then
  541. error("getmonstercountbymap param mapCfgId is nil")
  542. return
  543. end
  544. local line = msgData.line
  545. if not line then
  546. error("getmonstercountbymap param line is nil")
  547. return
  548. end
  549. local monsterCfgId = msgData.monsterCfgId
  550. if not monsterCfgId then
  551. error("getmonstercountbymap param monsterCfgId is nil")
  552. return
  553. end
  554. local state = msgData.state
  555. if not state then
  556. error("getmonstercountbymap param state is nil")
  557. return
  558. end
  559. local monsterCount = getmapmonstercountbyid(actor, tonumber(mapCfgId), tonumber(line), tonumber(monsterCfgId),
  560. tonumber(state))
  561. sendluamsg(
  562. actor,
  563. LuaMessageIdToClient.MONSTER_COUNT_RESULT,
  564. {
  565. mapCfgId = mapCfgId,
  566. line = line,
  567. monsterCfgId = monsterCfgId,
  568. state = state,
  569. monsterCount = monsterCount
  570. }
  571. )
  572. end
  573. ---根据boss表id获取怪物数量
  574. ---@param actor 玩家对象
  575. ---@param msgData 消息对象 id:cfg_BOSS_challenge表id、state:怪物状态(1:未死亡,0:所有)
  576. function DuplicateCommon.getmonstercountbyid(actor, msgData)
  577. local res = {}
  578. for _, value in pairs(msgData) do
  579. local id = value.id
  580. if not id then
  581. error("getmonstercountbyid param id is nil")
  582. return
  583. end
  584. local state = value.state
  585. if not state then
  586. error("getmonstercountbyid param state is nil")
  587. return
  588. end
  589. local tableResult = ConfigDataManager.getTable("cfg_BOSS_challenge", "id", id)
  590. if not tableResult or not next(tableResult) then
  591. error("getmonstercountbyid tableResult is nil")
  592. return
  593. end
  594. local monsterCfgId = tableResult[1].monsterid
  595. local mapId = tableResult[1].mapid
  596. local dupType = tableResult[1].monstertype
  597. local temp = {}
  598. for _, v in pairs(string.split(mapId, "|")) do
  599. local mapInfo = string.split(v, "#")
  600. for i = 2, #mapInfo, 2 do
  601. local mapCfgId = mapInfo[i - 1]
  602. local line = mapInfo[i]
  603. local monsterCount = this.getMosnterCount(actor, dupType, tonumber(mapCfgId), tonumber(line), tonumber(monsterCfgId), tonumber(state))
  604. table.insert(temp, {
  605. id = tonumber(id),
  606. mapCfgId = tonumber(mapCfgId),
  607. line = tonumber(line),
  608. monsterCfgId = tonumber(monsterCfgId),
  609. state = tonumber(state),
  610. monsterCount = tonumber(monsterCount)
  611. })
  612. end
  613. end
  614. res[id] = temp
  615. end
  616. sendluamsg(actor, LuaMessageIdToClient.MONSTER_COUNT_RESULT_BY_ID, res)
  617. end
  618. function DuplicateCommon.getchallengebossinfobyid(actor, msgData)
  619. local reviveInfos = MonsterScript.Getinfos()
  620. local res = {}
  621. for _, value in pairs(msgData) do
  622. local id = value.id
  623. if not id then
  624. error("getmonstercountbyid param id is nil")
  625. return
  626. end
  627. local tableResult = ConfigDataManager.getTable("cfg_BOSS_challenge", "id", id)
  628. if not tableResult or not next(tableResult) then
  629. error("getmonstercountbyid tableResult is nil")
  630. return
  631. end
  632. local monsterCfgId = tableResult[1].monsterid
  633. local mapId = tableResult[1].mapid
  634. local dupType = tableResult[1].monstertype
  635. local temp = {}
  636. for _, v in pairs(string.split(mapId, "|")) do
  637. local mapInfo = string.split(v, "#")
  638. for i = 2, #mapInfo, 2 do
  639. local mapCfgId = tonumber(mapInfo[i - 1])
  640. local line = tonumber(mapInfo[i])
  641. -- local monsterCount = this.getMosnterCount(actor, dupType, tonumber(mapCfgId), tonumber(line), tonumber(monsterCfgId), 1)
  642. -- table.insert(temp, {
  643. -- id = tonumber(id),
  644. -- mapCfgId = tonumber(mapCfgId),
  645. -- line = tonumber(line),
  646. -- monsterCfgId = tonumber(monsterCfgId),
  647. -- monsterCount = tonumber(monsterCount)
  648. -- })
  649. local info = reviveInfos[mapCfgId]
  650. local time = 0
  651. if info ~= nil and info[monsterCfgId] ~= nil and info[monsterCfgId][line] ~= nil then
  652. time = info[monsterCfgId][line]
  653. end
  654. -- local bossInfo = mapbossinfo(tonumber(mapId), tonumber(monsterCfgId))
  655. -- res[id] = bossInfo
  656. table.insert(temp, {
  657. id = tonumber(id),
  658. mapCfgId = tonumber(mapCfgId),
  659. line = tonumber(line),
  660. monsterCfgId = tonumber(monsterCfgId),
  661. monsterCount = tonumber(time)
  662. })
  663. end
  664. end
  665. res[id] = temp
  666. -- local monsterCfgId = tableResult[1].monsterid
  667. -- local mapIdList = tableResult[1].mapid
  668. -- local mapList = string.split(mapIdList, "|")
  669. -- local mapId = string.split(mapList[1], "#")[1]
  670. end
  671. sendluamsg(actor, LuaMessageIdToClient.RES_CHALLENGE_BOSS_INFO_BY_ID, res)
  672. end
  673. -- @description 退出游戏
  674. -- @param 玩家对象
  675. -- @return
  676. function DuplicateCommon.OfflineQuitGame(actor)
  677. local ready = getplaydef(actor, PlayerDefKey.DUP_TEAM_READY)
  678. if ready then
  679. DuplicateCommon.ChangeTeamPrepareState(actor, DupTeamChangeState.REFUSE)
  680. end
  681. end
  682. function this.getMosnterCount(actor, dupType, mapId, line, monsterId, state)
  683. if tonumber(dupType) == 5 then
  684. -- 跨服圣域BOSS, 缓存中获取
  685. return SanctuaryBoss.getMonsterCount(mapId, line, monsterId, state)
  686. end
  687. return getmapmonstercountbyid(actor, tonumber(mapId), tonumber(line), tonumber(monsterId), state)
  688. end
  689. ---更新副本任务进度
  690. function this.UpdateDupTask(actor, reqCfgId, dupType)
  691. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.FINISH_DUPLICATE, dupType)
  692. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.FINISH_GOAL_DUP, reqCfgId)
  693. end
  694. function this.RecordDupCount(actor, reqCfgId, dupType)
  695. this.RecordDupFinishCount(actor, dupType, PlayerDefKey.duplicate.DUP_TYPE_FINISH_COUNT)
  696. this.RecordDupFinishCount(actor, reqCfgId, PlayerDefKey.duplicate.DUP_FLOOR_FINISH_COUNT)
  697. end
  698. function this.RecordDupFinishCount(actor, countKey, varName)
  699. if string.isNullOrEmpty(varName) then
  700. return
  701. end
  702. local countRecord = getplaydef(actor, varName)
  703. if countRecord == nil then
  704. countRecord = {}
  705. end
  706. local oldCount = tonumber(countRecord[countKey])
  707. if oldCount == nil then
  708. oldCount = 0
  709. end
  710. countRecord[countKey] = oldCount + 1
  711. setplaydef(actor, varName, countRecord)
  712. end
  713. ---获取副本完成次数
  714. function DuplicateCommon.GetDupFinishCount(actor, countKey, varName)
  715. if varName == nil or countKey == nil then
  716. return 0
  717. end
  718. local countRecord = getplaydef(actor, varName)
  719. if table.isNullOrEmpty(countRecord) then
  720. return 0
  721. end
  722. local totalCount = countRecord[countKey]
  723. if totalCount == nil then
  724. return 0
  725. end
  726. return tonumber(totalCount)
  727. end
  728. ---@description 完成一次副本活动后调用
  729. ---@param actor table 玩家对象
  730. ---@param reqCfgId number cfg_rep的id
  731. function DuplicateCommon.FinishDupActivity(actor, reqCfgId)
  732. local typeParam = ConfigDataManager.getTableValue("cfg_rep", "type", "id", reqCfgId)
  733. if typeParam == nil then
  734. return
  735. end
  736. local dupType = tonumber(typeParam)
  737. local contains = table.contains(DuplicateType, dupType)
  738. ---未定义的副本类型
  739. if not contains then
  740. return
  741. end
  742. local cfgId = tonumber(reqCfgId)
  743. --更新副本完成次数
  744. this.RecordDupCount(actor, cfgId, dupType)
  745. --更新任务进度
  746. this.UpdateDupTask(actor, cfgId, dupType)
  747. end
  748. ---@description 扫荡副本
  749. ---@param actor 玩家对象
  750. ---@param configId number cfg_rep的id
  751. ---@param count number 扫荡副本次数
  752. function DuplicateCommon.sweepThroughDungeons(actor, configId, count)
  753. if DuplicateCommon.CheckEnterCountConditonCommon(actor, configId, count) ~= EnterLimitResultConst.ALLOW then
  754. return
  755. end
  756. local dupType = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  757. dupType = tonumber(dupType)
  758. if dupType == DuplicateType.COMBO_TEST then
  759. -- 连击试炼
  760. ComboTest.sweepThroughDungeons(actor, configId, count)
  761. end
  762. end
  763. -- @description 通用进入限制条件检查
  764. -- @param 玩家对象,cfg_rep的id
  765. -- @return EnterLimitResultConst
  766. function DuplicateCommon.CheckEnterCountConditonCommon(actor, configId, count)
  767. local playerLevel = tonumber(getbaseinfo(actor, "level"))
  768. local levelConfig = ConfigDataManager.getTableValue("cfg_rep", "level", "id", configId)
  769. if not string.isNullOrEmpty(levelConfig) then
  770. local levelList = string.split(levelConfig, "#")
  771. local minLevel = tonumber(levelList[1])
  772. local maxLevel = tonumber(levelList[2])
  773. if playerLevel < minLevel or playerLevel > maxLevel then
  774. print("等级不足")
  775. return EnterLimitResultConst.LEVEL
  776. end
  777. end
  778. local activityId = ConfigDataManager.getTableValue("cfg_rep", "type", "id", configId)
  779. local leftCount = getleftcountofactivity(actor, activityId)
  780. if leftCount <= 0 or leftCount < count then
  781. print("次数不足")
  782. return EnterLimitResultConst.COUNT
  783. end
  784. local itemString = ConfigDataManager.getTableValue("cfg_rep", "itemId", "id", configId)
  785. local itemTable = string.toIntIntMap(itemString, "#", "|")
  786. for itemId, needCount in pairs(itemTable) do
  787. itemId = tonumber(itemId)
  788. needCount = tonumber(needCount) * count
  789. local ownCount = getbagitemcountbyid(actor, itemId)
  790. if ownCount < needCount then
  791. print("道具不足", itemId, ownCount, needCount)
  792. return EnterLimitResultConst.ITEM
  793. end
  794. end
  795. return EnterLimitResultConst.ALLOW
  796. end