ActivityMonsterAttack.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. -- 怪物来袭活动
  2. MonAtk = {}
  3. local MONSTER_ATTACK_INFO_KEY = "G$MONSTER_ATTACK_INFO"
  4. local MOSNTER_ATTACKING_KEY = "G$MOSNTER_ATTACKING"
  5. local ITEM_PICK_COUNT_KEY = "J$_ITEM_PICK_COUNT"
  6. local DROP_INFO_KEY = "Q$_DROP_INFO_KEY"
  7. function MonAtk.getMonsterAttackInfo()
  8. local data = getsysvar(MONSTER_ATTACK_INFO_KEY)
  9. if data == nil then
  10. data = {}
  11. end
  12. return data
  13. end
  14. function MonAtk.setMonsterAttackInfo(monsterAttackInfo)
  15. setsysvar(MONSTER_ATTACK_INFO_KEY, monsterAttackInfo)
  16. end
  17. function MonAtk.isMonsterAttacking()
  18. local data = getsysvar(MOSNTER_ATTACKING_KEY)
  19. if data == nil then
  20. return false
  21. end
  22. return data
  23. end
  24. function MonAtk.setMonsterAttacking(ok)
  25. setsysvar(MOSNTER_ATTACKING_KEY, ok)
  26. end
  27. function MonAtk.getAttackConfig(actId)
  28. local configList = ConfigDataManager.getList("cfg_monster_attack")
  29. local result = {}
  30. for _, config in pairs(configList) do
  31. local ruleId = config["ruleid"]
  32. local items = string.split(ruleId, "#")
  33. if (table.contains(items, actId)) then
  34. table.insert(result, config)
  35. end
  36. end
  37. return result
  38. end
  39. function MonAtk.monsterGen(monsterAttackInfo, config)
  40. local safeTime = config["safetime"]
  41. local mapCfgId = config["mapid"]
  42. local lineId = config["line"]
  43. local monsterid = config["monid"]
  44. local coordinates = config["poz"]
  45. local range = config["range"]
  46. local count = 1
  47. local xy = string.split(coordinates, "#")
  48. local lines = string.split(lineId, "#")
  49. local x = xy[1]
  50. local y = xy[2]
  51. for _, line in pairs(lines) do
  52. local mapId = gamemap.getMapKey(mapCfgId, line)
  53. --生成怪物
  54. local monIds = mongen(mapId, x, y, range, monsterid, count)
  55. if table.isNullOrEmpty(monIds) then
  56. -- jprint("建怪物失败",monsterid,"mapid",mapId)
  57. else
  58. for _, mactor in pairs(monIds) do
  59. local monsterUid = mactor:toString()
  60. local now = getbaseinfo("now")
  61. local monsterInfo = {
  62. leaveAttackTime = now,
  63. safeTime = safeTime,
  64. mapId = mapId,
  65. monsterId = monsterid,
  66. invalid = false,
  67. }
  68. monsterAttackInfo[monsterUid] = monsterInfo
  69. --设置定时器
  70. setontimer(mactor, 1, 2)
  71. -- jprint("怪物来袭创建怪物",monsterUid, monsterid, mapId, mapCfgId, x, y)
  72. end
  73. end
  74. end
  75. end
  76. function MonAtk.monsterInfo(actor, monsterCfgId)
  77. local result = {}
  78. local monInfo = MonAtk.getMonsterAttackInfo()
  79. for id, m in pairs(monInfo) do
  80. local invalid = table.getValue(m, "invalid")
  81. if not invalid then
  82. local mapId = table.getValue(m, "mapId")
  83. local mid = table.getValue(m, "monsterId")
  84. local mapCfgId, mapLine = gamemap.parseMapKey(mapId)
  85. if tostring(mid) == tostring(monsterCfgId) then
  86. table.insert(result, {
  87. monsterid = mid,
  88. mapid = mapId,
  89. mapCfgId = mapCfgId,
  90. mapLine = mapLine,
  91. })
  92. end
  93. end
  94. end
  95. sendluamsg(actor, LuaMessageIdToClient.MONSTER_ATTACK_BOSS_INFO, result)
  96. end
  97. --在地图上移除怪物
  98. function MonAtk.removeMonster(actor, reason)
  99. --setofftimer(actor,1)
  100. local ok = removemapobject(actor)
  101. jprint("怪物来袭移除怪物", actor:toString(), reason, ok)
  102. end
  103. --定时器心跳,用于检查怪物删除
  104. function ontimer1(actor)
  105. --jprint(" MonAtk.isMonsterAttacking() ", MonAtk.isMonsterAttacking() )
  106. if MonAtk.isMonsterAttacking() then
  107. return
  108. end
  109. local monsterAttackInfo = MonAtk.getMonsterAttackInfo()
  110. local monsterUid = actor:toString()
  111. local monsterInfo = monsterAttackInfo[monsterUid]
  112. if table.isNullOrEmpty(monsterInfo) then
  113. --出问题了,把定怪物移除
  114. MonAtk.removeMonster(actor, "monsterinfo为空")
  115. return
  116. end
  117. local leaveAttackTime = monsterInfo["leaveAttackTime"]
  118. local isFighting = leaveAttackTime == 0
  119. if isFighting then
  120. --怪物如果是战斗状态,不管
  121. return
  122. end
  123. local now = getbaseinfo("now")
  124. local diffMills = tonumber(now) - tonumber(leaveAttackTime)
  125. local safeTime = monsterInfo["safeTime"]
  126. if string.isNullOrEmpty(safeTime) then
  127. safeTime = 0
  128. end
  129. local safeTimeMills = tonumber(safeTime) * 1000
  130. if not MonAtk.isMonsterAttacking() and diffMills >= safeTimeMills then
  131. --活动结束且怪物脱战时间大于指定的时间,则销毁怪物
  132. MonAtk.removeMonster(actor, "正常移除")
  133. monsterInfo["invalid"] = true
  134. MonAtk.setMonsterAttackInfo(monsterAttackInfo)
  135. end
  136. end
  137. function MonAtk.start(actId)
  138. --清空或者初始化数据
  139. MonAtk.setMonsterAttackInfo({})
  140. actId = tostring(actId)
  141. local configs = MonAtk.getAttackConfig(actId)
  142. if table.isNullOrEmpty(configs) then
  143. return
  144. end
  145. local monsterAttackInfo = MonAtk.getMonsterAttackInfo()
  146. for _, value in pairs(configs) do
  147. MonAtk.monsterGen(monsterAttackInfo, value)
  148. end
  149. MonAtk.setMonsterAttackInfo(monsterAttackInfo)
  150. MonAtk.setMonsterAttacking(true)
  151. end
  152. function MonAtk.stop(actId)
  153. MonAtk.setMonsterAttacking(false)
  154. --MonAtk.setMonsterAttackInfo({})
  155. end
  156. function MonAtk.monAtkMonsterEnterAttack(monActor, monsterConfgId)
  157. local monsterUid = tostring(monActor)
  158. local monsterInfo = MonAtk.getMonsterAttackInfo()[monsterUid]
  159. if table.isNullOrEmpty(monsterInfo) then
  160. return
  161. end
  162. monsterInfo["leaveAttackTime"] = 0
  163. end
  164. function MonAtk.monAtkMonsterLeaveAttack(monActor, monsterConfgId)
  165. local monsterUid = tostring(monActor)
  166. local monsterInfo = MonAtk.getMonsterAttackInfo()[monsterUid]
  167. if table.isNullOrEmpty(monsterInfo) then
  168. return
  169. end
  170. local now = getbaseinfo("now")
  171. monsterInfo["leaveAttackTime"] = now
  172. end
  173. function MonAtk.run(activityId, action)
  174. -- jprint("活动开始", activityId, action)
  175. if tonumber(action) == 1 then
  176. MonAtk.start(activityId)
  177. elseif tonumber(action) == 0 then
  178. MonAtk.stop(activityId)
  179. end
  180. end
  181. function MonAtk.getDropInfo()
  182. local dropInfo = getsysvar(DROP_INFO_KEY)
  183. if dropInfo == nil then
  184. dropInfo = {}
  185. end
  186. return dropInfo
  187. end
  188. function MonAtk.setDropInfo(dropInfo)
  189. setsysvar(DROP_INFO_KEY, dropInfo)
  190. end
  191. function MonAtk.monsterDieDrop(actor, dropData)
  192. local monsterUid = tostring(table.getValue(dropData, "monsterid"))
  193. local monsterAttackInfo = MonAtk.getMonsterAttackInfo()
  194. local monsterItem = monsterAttackInfo[monsterUid]
  195. if table.isNullOrEmpty(monsterItem) then
  196. return
  197. end
  198. local dropItems = table.getValue(dropData, "dropitems")
  199. local dropInfo = MonAtk.getDropInfo()
  200. local dropTime = getbaseinfo("now")
  201. for _, dropItem in pairs(dropItems) do
  202. local id = table.getValue(dropItem, "id")
  203. local cfgId = table.getValue(dropItem, "cfgid")
  204. local count = table.getValue(dropItem, "count")
  205. local dataItem = {
  206. cfgid = cfgId,
  207. count = count,
  208. droptime = dropTime
  209. }
  210. dropInfo[tostring(id)] = dataItem
  211. end
  212. -- jprint("setdropinfo", dropInfo, dropData)
  213. MonAtk.setDropInfo(dropInfo)
  214. monsterItem["invalid"] = true
  215. -- jprint("monsterItem", monsterItem)
  216. MonAtk.setMonsterAttackInfo(monsterAttackInfo)
  217. end
  218. function MonAtk.pickUpItem(actor, items)
  219. -- jprint("拾取",items)
  220. if not MonAtk.isMonsterAttacking() then
  221. return nil
  222. end
  223. if table.isNullOrEmpty(items) then
  224. return nil
  225. end
  226. for _, item in pairs(items) do
  227. local itemId = item["id"]
  228. --只处理第一项即可
  229. return MonAtk.checkPickUpItem(actor, itemId)
  230. end
  231. return nil
  232. end
  233. function MonAtk.addTodayPickUpCount(actor, itemId, itemCount)
  234. local pickCountInfo = getplaydef(actor, ITEM_PICK_COUNT_KEY)
  235. if pickCountInfo == nil then
  236. pickCountInfo = {}
  237. end
  238. local strItemId = tostring(itemId)
  239. local count = table.getValue(pickCountInfo, strItemId)
  240. if count == nil then
  241. count = 0
  242. end
  243. count = count + tonumber(itemCount)
  244. pickCountInfo[strItemId] = count
  245. --jprint("pickCountInfo", pickCountInfo)
  246. setplaydef(actor, ITEM_PICK_COUNT_KEY, pickCountInfo)
  247. end
  248. function MonAtk.getTodayPickCount(actor, itemId)
  249. local pickCountInfo = getplaydef(actor, ITEM_PICK_COUNT_KEY)
  250. if pickCountInfo == nil then
  251. return 0
  252. end
  253. local value = table.getValue(pickCountInfo, tostring(itemId))
  254. if value == nil then
  255. return 0
  256. end
  257. return tonumber(value)
  258. end
  259. function MonAtk.getPickCountLimit(itemCfgId)
  260. local value = ConfigDataManager.getTableValue("cfg_global", "value", "id", 3101)
  261. if value == nil then
  262. return -1
  263. end
  264. local map = string.toStringStringMap(value, "#", "|")
  265. local value = table.getValue(map, tostring(itemCfgId))
  266. if string.isNullOrEmpty(value) then
  267. return -1
  268. end
  269. return tonumber(value)
  270. end
  271. function MonAtk.checkPickUpItem(actor, itemId)
  272. local dropInfo = MonAtk.getDropInfo()
  273. --jprint("dropinfo", dropInfo)
  274. local dropItem = table.getValue(dropInfo, tostring(itemId))
  275. if dropItem == nil then
  276. return nil
  277. end
  278. local itemCfgId = table.getValue(dropItem, "cfgid")
  279. local count = table.getValue(dropItem, "count")
  280. local pickCount = MonAtk.getTodayPickCount(actor, itemCfgId)
  281. local pickLimit = MonAtk.getPickCountLimit(itemCfgId)
  282. jprint("checkPickUpItem", itemCfgId, pickCount, pickLimit)
  283. if pickLimit == -1 then
  284. return nil
  285. end
  286. if pickLimit > pickCount then
  287. if pickCount + count > pickLimit then
  288. local genCount = pickCount + count - pickLimit
  289. count = pickLimit - pickCount
  290. -- 剩余的数量重新生成
  291. -- local x = getbaseinfo(actor, "x")
  292. -- local y = getbaseinfo(actor, "y")
  293. -- local uniMapId = getbaseinfo(actor, "unimapid")
  294. -- throwitem(actor, uniMapId, x, y, 1, itemId, genCount)
  295. end
  296. MonAtk.addTodayPickUpCount(actor, itemCfgId, count)
  297. return {allow = true , count = count}
  298. else
  299. jprint("该物品今日拾取达到上限", itemCfgId)
  300. noticeTip.noticeinfo(actor,StringIdConst.TEXT336)
  301. return {allow = false}
  302. end
  303. end
  304. -- =================== 以下是public函数,测试用============================
  305. -- --活动开始
  306. -- function monatkstart(actor, actId)
  307. -- MonAtk.start(actId)
  308. -- end
  309. --活动结束
  310. --function monatkend(actor, actId)
  311. -- MonAtk.stop(actId)
  312. --end