PlayerPkValue.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. -- 玩家PK值功能
  2. pk = {}
  3. ---设置玩家pk值
  4. ---@param actor 玩家对象
  5. ---@param pkValue PK值
  6. function pk.setpkvalue(actor, pkValue)
  7. --特定的线路不增加PK值
  8. local mapUid = getbaseinfo(actor, "unimapid")
  9. local mapInfo = getmapinfobyid(actor, mapUid)
  10. if not table.isNullOrEmpty(mapInfo) then
  11. local mapCfgId = table.getValue(mapInfo, "cfgid")
  12. local mapLine = table.getValue(mapInfo, "line")
  13. local pkLine = ConfigDataManager.getTableValue("cfg_map_line", "pkline", "id", mapCfgId)
  14. if not string.isNullOrEmpty(pkLine) then
  15. local pkLines = string.split(pkLine, "|")
  16. for _, line in pairs(pkLines) do
  17. if tonumber(mapLine) == tonumber(line) then
  18. jprint("pk线路不增加PK值", mapUid, mapCfgId, mapLine, actor)
  19. return
  20. end
  21. end
  22. end
  23. end
  24. setplaydef(actor, PlayerDefKey.pkValue.PK_VALUE, pkValue)
  25. -- 获取附近角色,给每一个角色发送对应角色PK值变化的消息
  26. local sendPlayerIds = {}
  27. local nearPlayers = getnarplayer(actor)
  28. if nearPlayers or #nearPlayers > 0 then
  29. for i = 1, #nearPlayers do
  30. sendPlayerIds[i] = nearPlayers[i].luaplayer
  31. end
  32. sendPlayerIds[#sendPlayerIds + 1] = actor
  33. if sendPlayerIds and #sendPlayerIds > 0 then
  34. for i = 1, #sendPlayerIds do
  35. sendluamsg(sendPlayerIds[i], LuaMessageIdToClient.PK_VALUE_CHANGE, {
  36. rid = actor,
  37. pkValue = pkValue
  38. })
  39. end
  40. end
  41. else
  42. sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, {
  43. rid = actor,
  44. pkValue = tonumber(pk.getpkvalue(actor))
  45. })
  46. end
  47. end
  48. ---获取指定玩家PK值
  49. ---@param actor 玩家对象
  50. ---@return PK值
  51. function pk.getpkvalue(actor)
  52. local pkValue = getplaydef(actor, PlayerDefKey.pkValue.PK_VALUE)
  53. if not pkValue then
  54. return 0
  55. end
  56. return pkValue
  57. end
  58. ---击杀玩家处理
  59. ---@param actor 攻击玩家对象
  60. ---@param diePlayer 死亡玩家对象
  61. function pk.killplayerpkvaluehandle(actor, diePlayer)
  62. if RolandSeige.IsPlayerInRoland(actor) then
  63. return
  64. end
  65. -- 清除diePlayer身上存储的防卫时间信息
  66. setplaydef(diePlayer, PlayerDefKey.pkValue.LAST_ATTACK, {})
  67. -- 判断是否在防卫时间内击杀的玩家,如果在防卫时间内击杀玩家则不增加PK值
  68. local attackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK)
  69. local now = tonumber(getbaseinfo("now"))
  70. local defenseTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME)
  71. if attackInfo and next(attackInfo) then
  72. for index = 1, #attackInfo do
  73. if attackInfo[index].attackId == diePlayer then
  74. if defenseTime and now - tonumber(attackInfo[index].timeStamp) <= tonumber(defenseTime) then
  75. gameDebug.print(actor:toString() .. "在防卫时间内击杀了" .. tostring(diePlayer) .. " 不增加PK值")
  76. return
  77. end
  78. end
  79. end
  80. end
  81. -- 判断击杀的玩家是否是红名玩家,是红名玩家不增加PK值
  82. local redNameNeed = ConfigDataManager.getTableValue("cfg_pk_count", "redNameNeed", "id", 1)
  83. local diePlayerPkValue = pk.getpkvalue(diePlayer)
  84. if redNameNeed and redNameNeed ~= "" and diePlayerPkValue and tonumber(diePlayerPkValue) >= tonumber(redNameNeed) then
  85. gameDebug.print(actor:toString() .. "击杀了红名玩家" .. tostring(diePlayer) .. " 不增加PK值")
  86. return
  87. end
  88. -- 根据配表增加PK值
  89. local curPkValue = pk.getpkvalue(actor)
  90. if curPkValue and curPkValue ~= "" and curPkValue > 0 then
  91. local addByKill = 0
  92. local pkCountTable = ConfigDataManager.getList("cfg_pk_count")
  93. if pkCountTable or next(pkCountTable) then
  94. local maxPkValue = 0
  95. for i = 1, #pkCountTable do
  96. local nameColor = pkCountTable[i].namecolor
  97. local minPkValue = pk.getSplitByHash(nameColor)[1]
  98. maxPkValue = pk.getSplitByHash(nameColor)[2]
  99. if curPkValue >= tonumber(minPkValue) and curPkValue <= tonumber(maxPkValue) then
  100. addByKill = pkCountTable[i].addbykill
  101. end
  102. end
  103. if tonumber(addByKill) == 0 and tonumber(curPkValue) > tonumber(maxPkValue) then
  104. addByKill = pkCountTable[#pkCountTable].addbykill
  105. end
  106. if addByKill == 0 then
  107. addByKill = pkCountTable[1].addbykill
  108. end
  109. end
  110. pk.setpkvalue(actor, tonumber(addByKill) + tonumber(curPkValue))
  111. else
  112. local addByKill = ConfigDataManager.getTableValue("cfg_pk_count", "addByKill", "id", 1)
  113. pk.setpkvalue(actor, addByKill)
  114. end
  115. local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1)
  116. local splitString = pk.getSplitByHash(reduceByTime)
  117. if splitString then
  118. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1])
  119. else
  120. gameDebug.print("killplayerpkvaluehandle cfg_pk_count表reduceByTime is null")
  121. return
  122. end
  123. end
  124. ---玩家被攻击处理
  125. ---@param actor 玩家对象
  126. ---@param fightParam 被攻击参数 caster:攻击者对象、target:被攻击者对象、mapid:地图id、skillid:技能id、skilllevel:技能等级、castertype:攻击者类型、targettype:被攻击者类型
  127. function pk.underattackpkvaluehandle(actor, fightParam)
  128. -- 当玩家攻击玩家时进行后面的逻辑
  129. if fightParam.castertype and fightParam.targettype and fightParam.castertype == 1 and fightParam.targettype == 1 then
  130. local lastAttackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK)
  131. if not lastAttackInfo or lastAttackInfo == "" or not next(lastAttackInfo) then
  132. -- 没有玩家攻击时间信息存入新的
  133. local attackInfo = {
  134. attackId = fightParam.caster,
  135. timeStamp = tonumber(getbaseinfo("now"))
  136. }
  137. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, attackInfo)
  138. else
  139. -- 有玩家攻击时间信息遍历判断是否已经存在攻击者id
  140. -- 如果存在,判断时间是否超时,如果超时存入新的时间戳
  141. local exists = false
  142. local now = tonumber(getbaseinfo("now"))
  143. local defenseTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME)
  144. for index = 1, #lastAttackInfo do
  145. if tonumber(lastAttackInfo[index].attackId) == tonumber(fightParam.caster) then
  146. exists = true
  147. local lastTime = lastAttackInfo[index].timeStamp
  148. if defenseTime and (now - tonumber(lastTime)) > tonumber(defenseTime) then
  149. table.remove(lastAttackInfo, index)
  150. lastAttackInfo[#lastAttackInfo + 1] = {
  151. attackId = fightParam.caster,
  152. timeStamp = now
  153. }
  154. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo)
  155. end
  156. break
  157. end
  158. end
  159. -- 如果不存在则存入
  160. if not exists then
  161. lastAttackInfo[#lastAttackInfo + 1] = {
  162. attackId = fightParam.caster,
  163. timeStamp = tonumber(getbaseinfo("now"))
  164. }
  165. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo)
  166. end
  167. end
  168. end
  169. end
  170. ---怪物击杀PK值处理
  171. ---@param actor 玩家对象
  172. ---@param monsterCfgId 怪物configId
  173. ---@param monsterLevel 怪物等级
  174. function pk.killmonsterpkvaluehandle(actor, monsterCfgId, monsterLevel)
  175. local levelDiff = ConfigDataManager.getTableValue("cfg_pk_count", "levelDiff", "id", 1)
  176. local level = getbaseinfo(actor, "level")
  177. if tonumber(level) - tonumber(levelDiff) >= tonumber(monsterLevel) then
  178. return
  179. end
  180. local pkValue = pk.getpkvalue(actor)
  181. if pkValue and pkValue > 0 then
  182. local monsterType = ConfigDataManager.getTableValue("cfg_monster", "type", "id", monsterCfgId)
  183. local reduceByMonster = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByMonster", "id", 1)
  184. local time = pk.getSplitByHash(reduceByMonster)
  185. if time and next(time) then
  186. local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME)
  187. if reduceTime and reduceTime ~= "" then
  188. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(reduceTime) + tonumber(time[tonumber(monsterType)]))
  189. else
  190. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(time[tonumber(monsterType)]))
  191. end
  192. end
  193. end
  194. end
  195. ---角色PK值心跳
  196. ---@param actor 玩家对象
  197. function pk.SecondHeartPkValue(actor)
  198. local pkValue = pk.getpkvalue(actor)
  199. if pkValue and tonumber(pkValue) > 0 then
  200. local pkValueReduceTime = getplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME)
  201. if pkValueReduceTime and tonumber(pkValueReduceTime) > 0 then
  202. local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME)
  203. if reduceTime and tonumber(reduceTime) > 0 then
  204. if tonumber(reduceTime) >= tonumber(pkValueReduceTime) then
  205. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(reduceTime) - tonumber(pkValueReduceTime))
  206. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, 0)
  207. pkValueReduceTime = 0
  208. else
  209. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, tonumber(pkValueReduceTime) - tonumber(reduceTime))
  210. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, 0)
  211. return
  212. end
  213. else
  214. pkValueReduceTime = tonumber(pkValueReduceTime) - 5
  215. if pkValueReduceTime > 0 then
  216. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, pkValueReduceTime)
  217. return
  218. end
  219. end
  220. end
  221. if pkValueReduceTime and pkValueReduceTime <= 0 then
  222. local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1)
  223. local splitString = pk.getSplitByHash(reduceByTime)
  224. if splitString and next(splitString) then
  225. pk.setpkvalue(actor, pkValue - splitString[2])
  226. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1])
  227. end
  228. end
  229. else
  230. return
  231. end
  232. end
  233. ---免罪符使用PK值处理
  234. ---@param actor 玩家对象
  235. ---@param itemConfigId 道具configId
  236. ---@param count 数量
  237. function pk.exonerationcharmpkvaluehnadle(actor, itemConfigId, count)
  238. local value = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.EXONERATION_CHARM_MINUS_COUNT)
  239. for i = 1, tonumber(count) do
  240. if itemConfigId == ItemConfigId.EXONERATION_CHARM then
  241. if value then
  242. local pkValue = pk.getpkvalue(actor)
  243. if pkValue and pkValue > 0 then
  244. pkValue = tonumber(pkValue) - tonumber(value)
  245. if pkValue < 0 then
  246. pkValue = 0
  247. end
  248. end
  249. pk.setpkvalue(actor, pkValue)
  250. end
  251. end
  252. end
  253. end
  254. ---角色进入视野发送玩家的PK值
  255. ---@param actor 玩家对象
  256. function pk.sendenterviewpkvalue(actor, targetPlayer)
  257. sendluamsg(targetPlayer, LuaMessageIdToClient.PK_VALUE_CHANGE, {
  258. rid = actor,
  259. pkValue = tonumber(pk.getpkvalue(actor))
  260. })
  261. sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, {
  262. rid = targetPlayer,
  263. pkValue = tonumber(pk.getpkvalue(targetPlayer))
  264. })
  265. sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, {
  266. rid = actor,
  267. pkValue = tonumber(pk.getpkvalue(actor))
  268. })
  269. end
  270. ---获取字符串井号切割后的结果
  271. ---@param str 原字符串
  272. ---@return 切割后的table
  273. function pk.getSplitByHash(str)
  274. local data = string.split(str, "#")
  275. if data and next(data) then
  276. return data
  277. else
  278. return nil
  279. end
  280. end