EquipGuard_1.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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. local accumulatedHp = getplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"])) or 0
  168. accumulatedHp = accumulatedHp + targetHurt
  169. local changeHp = math.floor(accumulatedHp / 500)
  170. if changeHp > 0 then
  171. accumulatedHp = 0
  172. end
  173. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"]),accumulatedHp)
  174. -- -- this.printEG(tableHp)
  175. -- local coefficient = ConfigDataManager.getTableValue("cfg_equip_guard", "coefficient", "id", itemCfgId)
  176. -- if coefficient == nil or coefficient == "" then
  177. -- coefficient = 10000
  178. -- -- error("guardhpchange actor:" .. actor:toString() .. ",守护生命值计算公式系数 coefficient==nil itemCfgId:" .. itemCfgId)
  179. -- -- jprint("guardhpchange actor:" .. actor:toString() .. ",守护生命值计算公式系数 coefficient==nil itemCfgId:" .. itemCfgId)
  180. -- -- return
  181. -- end
  182. -- -- local changeHp = tonumber(targetHurt) * (tonumber(coefficient) / 10000)
  183. -- local attackSpeed = getattrinfo(actor,"attackSpeedBonus")
  184. -- local originalHp = 1 / attackSpeed * (tonumber(coefficient) / 10000)
  185. -- local accumulatedHp = getplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"])) or 0
  186. -- local newHp = accumulatedHp + originalHp
  187. -- if newHp < 1 then
  188. -- setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"]),newHp)
  189. -- return
  190. -- end
  191. -- local changeHp = math.floor(newHp)
  192. -- newHp = newHp - changeHp
  193. -- setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,guardEquip["id"]),newHp)
  194. -- jprint("guardhpchange actor:" .. actor:toString() .. ",扣血量:" .. changeHp .. ",守护生命值计算公式系数:" .. coefficient .. ",targetHurt:" .. targetHurt)
  195. local lid = guardEquip["id"]
  196. local toremove = {}
  197. local currHp = 0;-- 用于打印 销毁为0 扣血才显示当前血量
  198. for i, value in pairs(tableHp) do
  199. local id = value["id"]
  200. if id == lid then
  201. local hp = value["hp"]
  202. local results = hp - changeHp
  203. currHp = results
  204. if results > 0 then
  205. value["hp"] = results
  206. sendluamsg(actor, LuaMessageIdToClient.EQUIP_GUARD_RES, { id = id, hp = results })
  207. -- jprint("guardhpchange actor:" .. actor:toString() .. ",道具唯一id" .. tostring(lid) .. ",当前血量:" .. hp .. " ,剩余血量" .. results .. ",扣血量:" .. changeHp)
  208. else
  209. -- 销毁该装备
  210. -- 脱装 传穿戴拦索引
  211. -- this.printEG(actor, guardEquip)
  212. takeofftheequip(actor, guardEquip["equipindex"])
  213. -- 根据唯一id找背包索引
  214. local bagIdx = gainbagidxbyitemid(actor, lid)
  215. -- 通过背包索引删除该道具
  216. removeitembyidxlist(actor, { bagIdx }, 9999, '守护血量为0移除')
  217. info(actor, "玩家", actor, "守护血量为移除 守护id", itemCfgId, "cfgHp", cfgHp, "扣血量", changeHp, "当前血量", hp)
  218. -- 移除记录的道具
  219. table.insert(toremove, i)
  220. -- 累加器计数置为零
  221. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,lid),0)
  222. -- jprint("guardhpchange actor:" .. actor:toString() .. ",道具唯一id" .. tostring(lid) .. ",当前血量:" .. hp .. " ,剩余血量" .. results .. ",扣血量:" .. changeHp)
  223. end
  224. end
  225. end
  226. for _, v in pairs(toremove) do
  227. table.remove(tableHp, v)
  228. end
  229. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  230. -- jprint("guardhpchange actor:" .. actor:toString() .. ", 剩余血量:" .. currHp .. ",执行完成 扣血量:" .. changeHp .. ",守护生命值计算公式系数:" .. coefficient .. ",targetHurt:" .. targetHurt)
  231. --this.printEG(tableHp)
  232. end
  233. --- 登录发送所有守护信息
  234. function EquipGuard.login (actor)
  235. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP) or ""
  236. sendluamsg(actor, LuaMessageIdToClient.EQUIP_GUARD_ALL_RES, tableHp)
  237. end
  238. -- ===================================this分隔线==========================================================
  239. --- 获取守护装备
  240. function this.getEquipGuardEG (actor)
  241. local selfType = getbaseinfo(actor, "mapobjecttype")
  242. if selfType ~= MapObjectType.PLAYER then
  243. return
  244. end
  245. local equips = getputonequipinfo(actor)
  246. if equips == nil then
  247. return
  248. end
  249. for _, equip in pairs(equips) do
  250. if tonumber(equip["subtype"]) == EquipSubType.GUARD then
  251. -- jprint("getEquipGuardEG 找到守护装备 ,cfgId:" .. tostring(cfgId) .. ",subType:" .. tostring(subType))
  252. return equip
  253. end
  254. end
  255. return nil;
  256. end
  257. --- 道具移除或丢弃 守护血量信息删除
  258. function this.removeguardhp (actor, ids)
  259. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP) or {}
  260. local toremove = {}
  261. for _, id in pairs(ids) do
  262. for i, value in pairs(tableHp) do
  263. local currId = value["id"]
  264. if id == currId then
  265. -- 累加器计数置为零
  266. setplaydef(actor,string.format(EquipGuardVariable.EQUIP_ACCUMULATOR,currId),0)
  267. table.insert(toremove, i)
  268. end
  269. end
  270. end
  271. for _, v in pairs(toremove) do
  272. table.remove(tableHp, v)
  273. end
  274. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  275. -- jprint("removeguardhp actor:" .. actor:toString() .. " 移除血量信息成功 ,ids:" .. tostring(ids))
  276. end
  277. --- 清理守护数据
  278. function this.clearguarddata(actor)
  279. -- 新存的数据
  280. local equipGuardData = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_DATA)
  281. if equipGuardData ~= nil and next(equipGuardData) ~= nil then
  282. local skills = equipGuardData[EquipGuardConst.SKILL]
  283. if skills ~= nil and next(skills) ~= nil then
  284. removeskill(actor, skills)
  285. -- jprint("clearguarddata 移除技能成功 actor:" .. actor:toString() .. " ,移除技能成功 skills:" .. tostring(skills))
  286. end
  287. end
  288. addrolekmlattributes(actor, EquipGuardVariable.GUARD_ATTR, {})
  289. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_DATA, {})
  290. -- jprint("clearguarddata 清理成功 属性清空 actor:" .. actor:toString() .. " ,移除技能成功 skills:" .. tostring(skills))
  291. end
  292. function this.isguardequip(itemCfgId)
  293. local subType = ConfigDataManager.getTableValue("cfg_item", "subType", "id", itemCfgId)
  294. if subType == nil then
  295. error("isguardequip ,subType==nil itemCfgId:" .. itemCfgId)
  296. return true
  297. end
  298. local subType = tonumber(subType)
  299. if subType ~= EquipSubType.GUARD then
  300. -- jprint("isguardequip 不是守护装备 subType:" .. subType)
  301. return true
  302. end
  303. return false
  304. end
  305. -- ===================================测试函数分隔线==========================================================
  306. --- 测试方法
  307. function equipguardtest(actor)
  308. -- 设置当前穿戴的装备血量为1
  309. local guardEquip = this.getEquipGuardEG(actor)
  310. if guardEquip then
  311. local id = guardEquip["id"]
  312. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP)
  313. if tableHp then
  314. for k, v in pairs(tableHp) do
  315. if id == v["id"] then
  316. v["hp"] = 1
  317. break
  318. end
  319. end
  320. setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, tableHp)
  321. end
  322. end
  323. -- setplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP, {})
  324. -- jprint("测试守护 equipguardtest actor:" .. actor:toString() .. " 处理成功 结束")
  325. end
  326. --- 测试方法 打印守护血量
  327. function dayingtablehptest(actor)
  328. local tableHp = getplaydef(actor, EquipGuardVariable.EQUIP_GUARD_HP)
  329. if tableHp == nil then
  330. -- jprint("dayingtablehp actor:" .. actor:toString() .. " 打印守护血量 tableHp等于nil:")
  331. return
  332. end
  333. if tableHp then
  334. for k, v in pairs(tableHp) do
  335. -- jprint("dayingtablehp actor:" .. actor:toString() .. " 打印守护血量 k:" .. tostring(k) .. " ,id:" .. tostring(v["id"]) .. ",hp:" .. tostring(v["hp"]))
  336. end
  337. end
  338. end