EquipGuard.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. ---
  2. --- Created by zhouzhipeng.
  3. --- DateTime: 2024/8/15 上午9:18
  4. ---
  5. EquipGuard = {}
  6. local this = {}
  7. --- 守护装备变量
  8. EquipGuardVariable = {
  9. EQUIP_GUARD_HP = "T$守护装备血量",
  10. EQUIP_GUARD_SKILL = "T$守护装备添加的技能ID",-- 后续可以删除
  11. EQUIP_GUARD_DATA = "T$守护装备添加的数据",
  12. EQUIP_ACCUMULATOR = "T$accumulatedHp_%s",
  13. GUARD_ATTR = "guardAttr" -- 守护装备添加的属性
  14. }
  15. --- 守护特殊属性常量
  16. GuardAbilityConst = {
  17. AUTO_PICK = 1, -- 自动拾取
  18. EQUIP_SKILL = 2, -- 装备技能
  19. }
  20. --- 守护特殊属性常量
  21. EquipGuardConst = {
  22. ITEM_CFG_ID = "itemCfgId",
  23. SKILL = "skill",
  24. ATT = "att",
  25. }
  26. --- 穿戴触发守护装备
  27. function EquipGuard.putGuardEquip (actor, itemCfgId)
  28. if this.isguardequip(itemCfgId) then
  29. return
  30. end
  31. -- jprint("putguardequip actor:" .. actor:toString() .. ",穿装触发 itemCfgId:" .. itemCfgId)
  32. -- 先清理在重新添加
  33. this.clearguarddata(actor)
  34. local guardEquip = this.getEquipGuardEG(actor);
  35. if guardEquip == nil then
  36. return
  37. end
  38. -- 获得已经穿戴的守护
  39. local guardList = ConfigDataManager.getTable("cfg_equip_guard", "id", itemCfgId)
  40. if guardList == nil or next(guardList) == nil then
  41. error("putguardequip actor:" ..actor:toString() .. " cfg_equip_guard配置为空 guardList等于nil或next(guardList) == nil itemCfgId:" .. itemCfgId)
  42. return
  43. end
  44. local guardCfg = guardList[1]
  45. local saveTable = {}
  46. saveTable[EquipGuardConst.ITEM_CFG_ID] = itemCfgId
  47. -- 添加技能处理
  48. local ability = guardCfg["ability"]
  49. local abilityParameter = guardCfg["abilityparameter"]
  50. if tonumber(ability) == GuardAbilityConst.EQUIP_SKILL then
  51. if abilityParameter ~= nil and abilityParameter ~= "" then
  52. -- 添加技能
  53. local skillIds = string.split(abilityParameter, "#")
  54. -- jprint("putguardequip actor:" .. actor:toString() .. ",ability:" .. tostring(ability) .. ",abilityParameter:" .. tostring(abilityParameter))
  55. for _, skillId in pairs(skillIds) do
  56. -- jprint("putguardequip actor:" .. actor:toString() .. " 添加技能 skillId:" .. skillId)
  57. levelupskill(actor, skillId, 1)
  58. end
  59. --setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_SKILL, skillIds)
  60. saveTable[EquipGuardConst.SKILL] = skillIds
  61. end
  62. end
  63. -- 加属性处理
  64. local attr_map = {}
  65. local stage = guardCfg["stage"]
  66. if stage ~= nil and stage ~= "" then
  67. local stageCfg = string.split(stage, "&")
  68. for _, value in pairs(stageCfg) do
  69. local str = string.split(value, "#")
  70. attr_map[str[1]] = str[2]
  71. end
  72. addrolekmlattributes(actor, EquipGuardVariable.GUARD_ATTR, attr_map)
  73. saveTable[EquipGuardConst.ATT] = attr_map
  74. -- this.printEG(actor, attr_map)
  75. end
  76. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_DATA, saveTable)
  77. -- jprint("putguardequip actor:" .. actor:toString() .. ",穿装触发 itemCfgId:" .. itemCfgId .. " 穿戴触发守护装备成功 stage:" .. stage .. ",abilityParameter:" .. abilityParameter)
  78. end
  79. --- 脱装触发守护装备
  80. function EquipGuard.takeOffGuardEquip (actor, itemCfgId)
  81. -- jprint("takeoffguardequip actor:" .. actor:toString() .. ",脱装触发 itemCfgId:" .. itemCfgId)
  82. if this.isguardequip(itemCfgId) then
  83. return
  84. end
  85. -- 先清理在重新添加
  86. this.clearguarddata(actor)
  87. -- jprint("takeoffguardequip actor:" .. actor:toString() .. ",脱装触发 触发守护装备结束 itemCfgId:" .. itemCfgId)
  88. end
  89. --- 守护处理 初始化守护血量
  90. function EquipGuard.initGuardEquip (actor, ids, cfgId, oldCount, newCount)
  91. local cfg_item = ConfigDataManager.getById("cfg_item", cfgId)
  92. if table.isNullOrEmpty(cfg_item) then
  93. error("initguardequip actor:" .. actor:toString() .. " ,cfg_item is null itemCfgId:" .. cfgId)
  94. return
  95. end
  96. if tonumber(cfg_item.subtype) ~= EquipSubType.GUARD or tonumber(cfg_item.type) ~= ItemType.EQUIP then
  97. -- 只处理守护装备
  98. return
  99. end
  100. -- this.printEG(ids)
  101. --[[
  102. for k, v in pairs(ids) do
  103. jprint("initguardequip 背包变化 变化的唯一id k:" .. tostring(k) .. " ,id:" .. tostring(v))
  104. end
  105. ]]
  106. -- 给道具绑定生命值
  107. if tonumber(newCount) < tonumber(oldCount) then
  108. -- todo 考虑丢弃、销毁
  109. -- this.removeguardhp(actor, ids)
  110. jprint("initguardequip actor:" .. actor:toString() .. " 背包变化 移除道具生命值 cfgId:" .. cfgId .. ",oldCount:" .. oldCount .. ",newCount:" .. newCount)
  111. return
  112. end
  113. local cfgHp = ConfigDataManager.getTableValue("cfg_equip_guard", "hp", "id", cfgId)
  114. if string.isNullOrEmpty(cfgHp) then
  115. error("initguardequip actor:" .. actor:toString() .. " ,cfg_equip_guard表配置 hp==nil itemCfgId:" .. cfgId)
  116. return
  117. end
  118. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP) or {}
  119. for _, id in pairs(ids) do
  120. local isAdd = true
  121. for _, value in pairs(tableHp) do
  122. local currId = value["id"]
  123. if currId == id then
  124. isAdd = false
  125. end
  126. end
  127. if isAdd then
  128. -- 新的唯一id,添加守护生命值
  129. local hp = { id = id, hp = cfgHp }
  130. table.insert(tableHp, hp)
  131. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  132. sendluamsg(actor, LuaMessageIdToClient.EQUIP_GUARD_RES, hp)
  133. -- jprint("initguardequip actor:" .. actor:toString() .. " 给道具添加守护血量 ,id:" .. tostring(id) .. ",cfgId:" .. cfgId .. ",设置血量hp:" .. cfgHp)
  134. --[[
  135. for k, v in pairs(tableHp) do
  136. jprint("initguardequip actor:" .. actor:toString() .. " 打印个人存的全部守护血量信息 k:" .. tostring(k) .. " ,id:" .. tostring(v["id"]) .. ",hp:" .. tostring(v["hp"]))
  137. end
  138. ]]
  139. end
  140. end
  141. -- dayingtablehp(actor)
  142. -- jprint("initguardequip actor:" .. actor:toString() .. "背包变化 守护血量处理 cfgId:" .. cfgId .. ",subType:" .. subType .. ",oldCount:" .. oldCount .. ",newCount:" .. newCount)
  143. end
  144. --- 守护血量变化
  145. function EquipGuard.guardHpChange (actor, targetHurt)
  146. -- jprint("guardhpchange actor:" .. actor:toString() .. " 守护血量变化 开始" .. ",玩家受到伤害:" .. targetHurt)
  147. -- if targetHurt == nil or targetHurt < 1 then
  148. -- return
  149. -- end
  150. local guardEquip = this.getEquipGuardEG(actor)
  151. if guardEquip == nil then
  152. return
  153. end
  154. local itemCfgId = guardEquip["cfgid"]
  155. local cfgHp = ConfigDataManager.getTableValue("cfg_equip_guard", "hp", "id", itemCfgId)
  156. if string.isNullOrEmpty(cfgHp) then
  157. cfgHp = "0"
  158. end
  159. if cfgHp == "0" then
  160. -- 无限血量无需扣血
  161. return
  162. end
  163. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP)
  164. if tableHp == nil then
  165. return
  166. end
  167. -- this.printEG(tableHp)
  168. local coefficient = ConfigDataManager.getTableValue("cfg_equip_guard", "coefficient", "id", itemCfgId)
  169. if coefficient == nil or coefficient == "" then
  170. coefficient = 10000
  171. -- error("guardhpchange actor:" .. actor:toString() .. ",守护生命值计算公式系数 coefficient==nil itemCfgId:" .. itemCfgId)
  172. -- jprint("guardhpchange actor:" .. actor:toString() .. ",守护生命值计算公式系数 coefficient==nil itemCfgId:" .. itemCfgId)
  173. -- return
  174. end
  175. -- local changeHp = tonumber(targetHurt) * (tonumber(coefficient) / 10000)
  176. local attackSpeed = getattrinfo(actor,"attackSpeedBonus")
  177. local originalHp = 1 / attackSpeed * (tonumber(coefficient) / 10000)
  178. local accumulatedHp = getplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"])) or 0
  179. local newHp = accumulatedHp + originalHp
  180. if newHp < 1 then
  181. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"]),newHp)
  182. return
  183. end
  184. local changeHp = math.floor(newHp)
  185. newHp = newHp - changeHp
  186. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"]),newHp)
  187. -- jprint("guardhpchange actor:" .. actor:toString() .. ",扣血量:" .. changeHp .. ",守护生命值计算公式系数:" .. coefficient .. ",targetHurt:" .. targetHurt)
  188. local lid = guardEquip["id"]
  189. local toremove = {}
  190. local currHp = 0;-- 用于打印 销毁为0 扣血才显示当前血量
  191. for i, value in pairs(tableHp) do
  192. local id = value["id"]
  193. if id == lid then
  194. local hp = value["hp"]
  195. local results = hp - changeHp
  196. currHp = results
  197. if results > 0 then
  198. value["hp"] = results
  199. sendluamsg(actor, LuaMessageIdToClient.EQUIP_GUARD_RES, { id = id, hp = results })
  200. -- jprint("guardhpchange actor:" .. actor:toString() .. ",道具唯一id" .. tostring(lid) .. ",当前血量:" .. hp .. " ,剩余血量" .. results .. ",扣血量:" .. changeHp)
  201. else
  202. -- 销毁该装备
  203. -- 脱装 传穿戴拦索引
  204. -- this.printEG(actor, guardEquip)
  205. takeofftheequip(actor, guardEquip["equipindex"])
  206. -- 根据唯一id找背包索引
  207. local bagIdx = gainbagidxbyitemid(actor, lid)
  208. -- 通过背包索引删除该道具
  209. removeitembyidxlist(actor, { bagIdx }, 9999, '守护血量为0移除')
  210. info(actor, "玩家", actor, "守护血量为移除 守护id", itemCfgId, "cfgHp", cfgHp, "扣血量", changeHp, "当前血量", hp)
  211. -- 移除记录的道具
  212. table.insert(toremove, i)
  213. -- 累加器计数置为零
  214. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,lid),0)
  215. -- jprint("guardhpchange actor:" .. actor:toString() .. ",道具唯一id" .. tostring(lid) .. ",当前血量:" .. hp .. " ,剩余血量" .. results .. ",扣血量:" .. changeHp)
  216. end
  217. end
  218. end
  219. for _, v in pairs(toremove) do
  220. table.remove(tableHp, v)
  221. end
  222. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  223. -- jprint("guardhpchange actor:" .. actor:toString() .. ", 剩余血量:" .. currHp .. ",执行完成 扣血量:" .. changeHp .. ",守护生命值计算公式系数:" .. coefficient .. ",targetHurt:" .. targetHurt)
  224. --this.printEG(tableHp)
  225. end
  226. --- 登录发送所有守护信息
  227. function EquipGuard.login (actor)
  228. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP) or ""
  229. sendluamsg(actor, LuaMessageIdToClient.EQUIP_GUARD_ALL_RES, tableHp)
  230. end
  231. -- ===================================this分隔线==========================================================
  232. --- 获取守护装备
  233. function this.getEquipGuardEG (actor)
  234. local equips = getputonequipinfo(actor)
  235. if equips == nil then
  236. return
  237. end
  238. for _, equip in pairs(equips) do
  239. if tonumber(equip["subtype"]) == EquipSubType.GUARD then
  240. -- jprint("getEquipGuardEG 找到守护装备 ,cfgId:" .. tostring(cfgId) .. ",subType:" .. tostring(subType))
  241. return equip
  242. end
  243. end
  244. return nil;
  245. end
  246. --- 道具移除或丢弃 守护血量信息删除
  247. function this.removeguardhp (actor, ids)
  248. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP) or {}
  249. local toremove = {}
  250. for _, id in pairs(ids) do
  251. for i, value in pairs(tableHp) do
  252. local currId = value["id"]
  253. if id == currId then
  254. -- 累加器计数置为零
  255. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,currId),0)
  256. table.insert(toremove, i)
  257. end
  258. end
  259. end
  260. for _, v in pairs(toremove) do
  261. table.remove(tableHp, v)
  262. end
  263. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  264. -- jprint("removeguardhp actor:" .. actor:toString() .. " 移除血量信息成功 ,ids:" .. tostring(ids))
  265. end
  266. --- 清理守护数据
  267. function this.clearguarddata(actor)
  268. -- 新存的数据
  269. local equipGuardData = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_DATA)
  270. if equipGuardData ~= nil and next(equipGuardData) ~= nil then
  271. local skills = equipGuardData[EquipGuardConst.SKILL]
  272. if skills ~= nil and next(skills) ~= nil then
  273. removeskill(actor, skills)
  274. -- jprint("clearguarddata 移除技能成功 actor:" .. actor:toString() .. " ,移除技能成功 skills:" .. tostring(skills))
  275. end
  276. end
  277. addrolekmlattributes(actor, EquipGuardVariable.GUARD_ATTR, {})
  278. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_DATA, {})
  279. -- jprint("clearguarddata 清理成功 属性清空 actor:" .. actor:toString() .. " ,移除技能成功 skills:" .. tostring(skills))
  280. end
  281. function this.isguardequip(itemCfgId)
  282. local subType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", itemCfgId)
  283. if subType == nil then
  284. error("isguardequip ,subType==nil itemCfgId:" .. itemCfgId)
  285. return true
  286. end
  287. local subType = tonumber(subType)
  288. if subType ~= EquipSubType.GUARD then
  289. -- jprint("isguardequip 不是守护装备 subType:" .. subType)
  290. return true
  291. end
  292. return false
  293. end
  294. -- ===================================测试函数分隔线==========================================================
  295. --- 测试方法
  296. function equipguardtest(actor)
  297. -- 设置当前穿戴的装备血量为1
  298. local guardEquip = this.getEquipGuardEG(actor)
  299. if guardEquip then
  300. local id = guardEquip["id"]
  301. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP)
  302. if tableHp then
  303. for k, v in pairs(tableHp) do
  304. if id == v["id"] then
  305. v["hp"] = 1
  306. break
  307. end
  308. end
  309. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  310. end
  311. end
  312. -- setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, {})
  313. jprint("测试守护 equipguardtest actor:" .. actor:toString() .. " 处理成功 结束")
  314. end
  315. --- 测试方法 打印守护血量
  316. function dayingtablehptest(actor)
  317. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP)
  318. if tableHp == nil then
  319. jprint("dayingtablehp actor:" .. actor:toString() .. " 打印守护血量 tableHp等于nil:")
  320. return
  321. end
  322. if tableHp then
  323. for k, v in pairs(tableHp) do
  324. jprint("dayingtablehp actor:" .. actor:toString() .. " 打印守护血量 k:" .. tostring(k) .. " ,id:" .. tostring(v["id"]) .. ",hp:" .. tostring(v["hp"]))
  325. end
  326. end
  327. end