PlayerPkValue.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. -- 玩家PK值功能
  2. pk = {}
  3. DropEquipType = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
  4. ---设置玩家pk值
  5. ---@param actor 玩家对象
  6. ---@param pkValue PK值
  7. function pk.setpkvalue(actor, pkValue)
  8. --特定的线路不增加PK值
  9. local mapUid = getbaseinfo(actor, "unimapid")
  10. local mapInfo = getmapinfobyid(actor, mapUid)
  11. if not table.isNullOrEmpty(mapInfo) then
  12. local mapCfgId = table.getValue(mapInfo, "cfgid")
  13. local mapLine = table.getValue(mapInfo, "line")
  14. local pkLine = ConfigDataManager.getTableValue("cfg_map_line", "pkline", "id", mapCfgId)
  15. if not string.isNullOrEmpty(pkLine) then
  16. local pkLines = string.split(pkLine, "|")
  17. for _, line in pairs(pkLines) do
  18. if tonumber(mapLine) == tonumber(line) then
  19. jprint("pk线路不增加PK值", mapUid, mapCfgId, mapLine, actor)
  20. return
  21. end
  22. end
  23. end
  24. end
  25. setplaydef(actor, PlayerDefKey.pkValue.PK_VALUE, pkValue)
  26. -- 获取附近角色,给每一个角色发送对应角色PK值变化的消息
  27. local sendPlayerIds = {}
  28. local nearPlayers = getnarplayer(actor)
  29. if nearPlayers or #nearPlayers > 0 then
  30. for i = 1, #nearPlayers do
  31. sendPlayerIds[i] = nearPlayers[i].luaplayer
  32. end
  33. sendPlayerIds[#sendPlayerIds + 1] = actor
  34. if sendPlayerIds and #sendPlayerIds > 0 then
  35. for i = 1, #sendPlayerIds do
  36. sendluamsg(
  37. sendPlayerIds[i],
  38. LuaMessageIdToClient.PK_VALUE_CHANGE,
  39. {
  40. rid = actor,
  41. pkValue = pkValue
  42. }
  43. )
  44. end
  45. end
  46. else
  47. sendluamsg(
  48. actor,
  49. LuaMessageIdToClient.PK_VALUE_CHANGE,
  50. {
  51. rid = actor,
  52. pkValue = tonumber(pk.getpkvalue(actor))
  53. }
  54. )
  55. end
  56. end
  57. ---获取指定玩家PK值
  58. ---@param actor 玩家对象
  59. ---@return PK值
  60. function pk.getpkvalue(actor)
  61. local pkValue = getplaydef(actor, PlayerDefKey.pkValue.PK_VALUE)
  62. if not pkValue then
  63. return 0
  64. end
  65. return pkValue
  66. end
  67. ---击杀玩家处理
  68. ---@param actor 攻击玩家对象
  69. ---@param diePlayer 死亡玩家对象
  70. function pk.killplayerpkvaluehandle(actor, diePlayer)
  71. if RolandSeige.IsPlayerInRoland(actor) then
  72. return
  73. end
  74. -- 清除diePlayer身上存储的防卫时间信息
  75. setplaydef(diePlayer, PlayerDefKey.pkValue.LAST_ATTACK, {})
  76. -- 判断是否在防卫时间内击杀的玩家,如果在防卫时间内击杀玩家则不增加PK值
  77. local attackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK)
  78. local now = tonumber(getbaseinfo("now"))
  79. local defenseTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME)
  80. if attackInfo and next(attackInfo) then
  81. for index = 1, #attackInfo do
  82. if attackInfo[index].attackId == diePlayer then
  83. if defenseTime and now - tonumber(attackInfo[index].timeStamp) <= tonumber(defenseTime) then
  84. gameDebug.print(actor:toString() .. "在防卫时间内击杀了" .. tostring(diePlayer) .. " 不增加PK值")
  85. return
  86. end
  87. end
  88. end
  89. end
  90. -- 判断击杀的玩家是否是红名玩家,是红名玩家不增加PK值
  91. local redNameNeed = ConfigDataManager.getTableValue("cfg_pk_count", "redNameNeed", "id", 1)
  92. local diePlayerPkValue = pk.getpkvalue(diePlayer)
  93. if redNameNeed and redNameNeed ~= "" and diePlayerPkValue and tonumber(diePlayerPkValue) >= tonumber(redNameNeed) then
  94. gameDebug.print(actor:toString() .. "击杀了红名玩家" .. tostring(diePlayer) .. " 不增加PK值")
  95. return
  96. end
  97. -- 根据配表增加PK值
  98. local curPkValue = pk.getpkvalue(actor)
  99. if curPkValue and curPkValue ~= "" and curPkValue > 0 then
  100. local addByKill = 0
  101. local pkCountTable = ConfigDataManager.getList("cfg_pk_count")
  102. if pkCountTable or next(pkCountTable) then
  103. local maxPkValue = 0
  104. for i = 1, #pkCountTable do
  105. local nameColor = pkCountTable[i].namecolor
  106. local minPkValue = pk.getSplitByHash(nameColor)[1]
  107. maxPkValue = pk.getSplitByHash(nameColor)[2]
  108. if curPkValue >= tonumber(minPkValue) and curPkValue <= tonumber(maxPkValue) then
  109. addByKill = pkCountTable[i].addbykill
  110. end
  111. end
  112. if tonumber(addByKill) == 0 and tonumber(curPkValue) > tonumber(maxPkValue) then
  113. addByKill = pkCountTable[#pkCountTable].addbykill
  114. end
  115. if addByKill == 0 then
  116. addByKill = pkCountTable[1].addbykill
  117. end
  118. end
  119. pk.setpkvalue(actor, tonumber(addByKill) + tonumber(curPkValue))
  120. else
  121. local addByKill = ConfigDataManager.getTableValue("cfg_pk_count", "addByKill", "id", 1)
  122. pk.setpkvalue(actor, addByKill)
  123. end
  124. local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1)
  125. local splitString = pk.getSplitByHash(reduceByTime)
  126. if splitString then
  127. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1])
  128. else
  129. gameDebug.print("killplayerpkvaluehandle cfg_pk_count表reduceByTime is null")
  130. return
  131. end
  132. end
  133. ---玩家被攻击处理
  134. ---@param actor 玩家对象
  135. ---@param fightParam 被攻击参数 caster:攻击者对象、target:被攻击者对象、mapid:地图id、skillid:技能id、skilllevel:技能等级、castertype:攻击者类型、targettype:被攻击者类型
  136. function pk.underattackpkvaluehandle(actor, fightParam)
  137. -- 当玩家攻击玩家时进行后面的逻辑
  138. if fightParam.castertype and fightParam.targettype and fightParam.castertype == 1 and fightParam.targettype == 1 then
  139. local lastAttackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK)
  140. if not lastAttackInfo or lastAttackInfo == "" or not next(lastAttackInfo) then
  141. -- 没有玩家攻击时间信息存入新的
  142. local attackInfo = {
  143. attackId = fightParam.caster,
  144. timeStamp = tonumber(getbaseinfo("now"))
  145. }
  146. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, attackInfo)
  147. else
  148. -- 有玩家攻击时间信息遍历判断是否已经存在攻击者id
  149. -- 如果存在,判断时间是否超时,如果超时存入新的时间戳
  150. local exists = false
  151. local now = tonumber(getbaseinfo("now"))
  152. local defenseTime =
  153. ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME)
  154. for index = 1, #lastAttackInfo do
  155. if tonumber(lastAttackInfo[index].attackId) == tonumber(fightParam.caster) then
  156. exists = true
  157. local lastTime = lastAttackInfo[index].timeStamp
  158. if defenseTime and (now - tonumber(lastTime)) > tonumber(defenseTime) then
  159. table.remove(lastAttackInfo, index)
  160. lastAttackInfo[#lastAttackInfo + 1] = {
  161. attackId = fightParam.caster,
  162. timeStamp = now
  163. }
  164. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo)
  165. end
  166. break
  167. end
  168. end
  169. -- 如果不存在则存入
  170. if not exists then
  171. lastAttackInfo[#lastAttackInfo + 1] = {
  172. attackId = fightParam.caster,
  173. timeStamp = tonumber(getbaseinfo("now"))
  174. }
  175. setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo)
  176. end
  177. end
  178. end
  179. end
  180. ---怪物击杀PK值处理
  181. ---@param actor 玩家对象
  182. ---@param monsterCfgId 怪物configId
  183. ---@param monsterLevel 怪物等级
  184. function pk.killmonsterpkvaluehandle(actor, monsterCfgId, monsterLevel)
  185. local levelDiff = ConfigDataManager.getTableValue("cfg_pk_count", "levelDiff", "id", 1)
  186. local level = getbaseinfo(actor, "level")
  187. if tonumber(level) - tonumber(levelDiff) >= tonumber(monsterLevel) then
  188. return
  189. end
  190. local pkValue = pk.getpkvalue(actor)
  191. if pkValue and pkValue > 0 then
  192. local monsterType = ConfigDataManager.getTableValue("cfg_monster", "type", "id", monsterCfgId)
  193. local reduceByMonster = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByMonster", "id", 1)
  194. local time = pk.getSplitByHash(reduceByMonster)
  195. if time and next(time) then
  196. local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME)
  197. if reduceTime and reduceTime ~= "" then
  198. setplaydef(
  199. actor,
  200. PlayerDefKey.pkValue.REDUCE_TIME,
  201. tonumber(reduceTime) + tonumber(time[tonumber(monsterType)])
  202. )
  203. else
  204. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(time[tonumber(monsterType)]))
  205. end
  206. end
  207. end
  208. end
  209. ---角色PK值心跳
  210. ---@param actor 玩家对象
  211. function pk.SecondHeartPkValue(actor)
  212. local pkValue = pk.getpkvalue(actor)
  213. if pkValue and tonumber(pkValue) > 0 then
  214. local pkValueReduceTime = getplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME)
  215. if pkValueReduceTime and tonumber(pkValueReduceTime) > 0 then
  216. local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME)
  217. if reduceTime and tonumber(reduceTime) > 0 then
  218. if tonumber(reduceTime) >= tonumber(pkValueReduceTime) then
  219. setplaydef(
  220. actor,
  221. PlayerDefKey.pkValue.REDUCE_TIME,
  222. tonumber(reduceTime) - tonumber(pkValueReduceTime)
  223. )
  224. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, 0)
  225. pkValueReduceTime = 0
  226. else
  227. setplaydef(
  228. actor,
  229. PlayerDefKey.pkValue.PK_REDUCE_TIME,
  230. tonumber(pkValueReduceTime) - tonumber(reduceTime)
  231. )
  232. setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, 0)
  233. return
  234. end
  235. else
  236. pkValueReduceTime = tonumber(pkValueReduceTime) - 5
  237. if pkValueReduceTime > 0 then
  238. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, pkValueReduceTime)
  239. return
  240. end
  241. end
  242. end
  243. if pkValueReduceTime and pkValueReduceTime <= 0 then
  244. local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1)
  245. local splitString = pk.getSplitByHash(reduceByTime)
  246. if splitString and next(splitString) then
  247. pk.setpkvalue(actor, pkValue - splitString[2])
  248. setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1])
  249. end
  250. end
  251. else
  252. return
  253. end
  254. end
  255. ---免罪符使用PK值处理
  256. ---@param actor 玩家对象
  257. ---@param itemConfigId 道具configId
  258. ---@param count 数量
  259. function pk.exonerationcharmpkvaluehnadle(actor, itemConfigId, count)
  260. local value =
  261. ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.EXONERATION_CHARM_MINUS_COUNT)
  262. for i = 1, tonumber(count) do
  263. if itemConfigId == ItemConfigId.EXONERATION_CHARM then
  264. if value then
  265. local pkValue = pk.getpkvalue(actor)
  266. if pkValue and pkValue > 0 then
  267. pkValue = tonumber(pkValue) - tonumber(value)
  268. if pkValue < 0 then
  269. pkValue = 0
  270. end
  271. end
  272. pk.setpkvalue(actor, pkValue)
  273. end
  274. end
  275. end
  276. end
  277. ---角色进入视野发送玩家的PK值
  278. ---@param actor 玩家对象
  279. function pk.sendenterviewpkvalue(actor, targetPlayer)
  280. sendluamsg(
  281. targetPlayer,
  282. LuaMessageIdToClient.PK_VALUE_CHANGE,
  283. {
  284. rid = actor,
  285. pkValue = tonumber(pk.getpkvalue(actor))
  286. }
  287. )
  288. sendluamsg(
  289. actor,
  290. LuaMessageIdToClient.PK_VALUE_CHANGE,
  291. {
  292. rid = targetPlayer,
  293. pkValue = tonumber(pk.getpkvalue(targetPlayer))
  294. }
  295. )
  296. sendluamsg(
  297. actor,
  298. LuaMessageIdToClient.PK_VALUE_CHANGE,
  299. {
  300. rid = actor,
  301. pkValue = tonumber(pk.getpkvalue(actor))
  302. }
  303. )
  304. end
  305. ---获取字符串井号切割后的结果
  306. ---@param str 原字符串
  307. ---@return 切割后的table
  308. function pk.getSplitByHash(str)
  309. local data = string.split(str, "#")
  310. if data and next(data) then
  311. return data
  312. else
  313. return nil
  314. end
  315. end
  316. -- 玩家被击杀
  317. function pk.PlayerDie(actor, dieInfo, killInfo)
  318. local killerType = killInfo.type
  319. if killerType ~= MapObjectType.PLAYER then
  320. return
  321. end
  322. local killerId = killInfo.id
  323. local killer = getactor(actor, killerId)
  324. local killerName = killInfo.name
  325. local mapCfgId = dieInfo.mapCfgId
  326. local pkValue = pk.getpkvalue(actor)
  327. -- 根据表数据获取掉落道具及掉落装备概率
  328. if not pkValue or pkValue == "" or pkValue <= 0 then
  329. return
  330. end
  331. local oneTable
  332. local pkCountTable = ConfigDataManager.getList("cfg_pk_count")
  333. if pkCountTable or next(pkCountTable) then
  334. for i = 1, #pkCountTable do
  335. local nameColor = pkCountTable[i].namecolor
  336. local minPkValue = pk.getSplitByHash(nameColor)[1]
  337. local maxPkValue = pk.getSplitByHash(nameColor)[2]
  338. if pkValue >= tonumber(minPkValue) and pkValue <= tonumber(maxPkValue) then
  339. oneTable = pkCountTable[i]
  340. end
  341. end
  342. end
  343. if oneTable == nil then
  344. return
  345. end
  346. local mapId = getbaseinfo(actor, "unimapid")
  347. local x = getbaseinfo(actor, "x")
  348. local y = getbaseinfo(actor, "y")
  349. -- 被击杀掉落道具
  350. local dropItem = string.split(oneTable.dropitem, "#")
  351. local itemCfgId = tonumber(dropItem[1])
  352. local count = tonumber(dropItem[2])
  353. local itemConfig = ConfigDataManager.getById("cfg_item", itemCfgId)
  354. if tonumber(itemConfig.type) == ItemType.EQUIP then
  355. -- 暂时不会配置装备
  356. else
  357. -- 非装备扣除数量然后地上生成
  358. local ownCount = getbagitemcountbyid(actor, itemCfgId)
  359. if ownCount < count then
  360. count = ownCount
  361. end
  362. if count > 0 then
  363. local dropTime = string.tonumber(ConfigDataManager.getTableValue("cfg_item", "dropTime", "id", itemCfgId)) + 1000
  364. removeitemfrombag(actor, itemCfgId, count, 0, 9999, "红名惩罚")
  365. throwitem(killer, mapId, x, y, 1, itemCfgId, count, dropTime, 3, 0)
  366. info("红名惩罚:玩家死亡掉落道具。", actor:toString(), itemCfgId, count)
  367. -- 发邮件
  368. local itemName = itemConfig.name
  369. sendconfigmailbyrid(actor, getbaseinfo(actor, "rid"), MailConfig.PK_DROP_ITEM, {}, killerName .. "#" .. count .. "#" .. itemName)
  370. end
  371. end
  372. -- 被击杀掉落穿戴装备概率
  373. local dropRate = string.tonumber(oneTable.dropequip) / 10000
  374. if math.selectRate(dropRate) then
  375. -- 先从背包找
  376. local isDroped = false
  377. local allItemInfo = getallbagiteminfo(actor)
  378. math.shuffleTable(allItemInfo)
  379. for _, oneItem in pairs(allItemInfo) do
  380. -- 装备且非绑定状态
  381. if oneItem.type == ItemType.EQUIP then
  382. if oneItem.isbind == false then
  383. local equipCfgId = oneItem.cfgid
  384. local subType = tonumber(ConfigDataManager.getTableValue("cfg_item", "subType", "id", equipCfgId))
  385. if table.contains(DropEquipType, subType) then
  386. isDroped = true
  387. -- 从背包掉落道具
  388. local dropTime = string.tonumber(ConfigDataManager.getTableValue("cfg_item", "dropTime", "id", equipCfgId)) + 1000
  389. dropequip(actor, oneItem.id, killerId, dropTime)
  390. info("红名惩罚:玩家死亡掉落装备。", actor:toString(), oneItem)
  391. -- 发邮件
  392. local equipName = ConfigDataManager.getTableValue("cfg_item", "name", "id", equipCfgId)
  393. sendconfigmailbyrid(actor, getbaseinfo(actor, "rid"), MailConfig.PK_DROP_EQUIP, {}, killerName .. "#" .. equipName)
  394. break
  395. end
  396. end
  397. end
  398. end
  399. if not isDroped then
  400. -- 从穿戴栏找
  401. local allEquip = getputonequipinfo(actor)
  402. math.shuffleTable(allEquip)
  403. for _, oneEquip in pairs(allEquip) do
  404. if oneEquip.isbind == false then
  405. if table.contains(DropEquipType, oneEquip.subtype) then
  406. local equipCfgId = oneEquip.cfgid
  407. local dropTime = string.tonumber(ConfigDataManager.getTableValue("cfg_item", "dropTime", "id", equipCfgId)) + 1000
  408. dropequip(actor, oneEquip.id, killerId, dropTime)
  409. info("红名惩罚:玩家死亡掉落装备。", actor:toString(), oneEquip)
  410. -- 发邮件
  411. local equipName = ConfigDataManager.getTableValue("cfg_item", "name", "id", equipCfgId)
  412. sendconfigmailbyrid(actor, getbaseinfo(actor, "rid"), MailConfig.PK_DROP_EQUIP, {}, killerName .. "#" .. equipName)
  413. break
  414. end
  415. end
  416. end
  417. end
  418. end
  419. end