-- 玩家PK值功能 pk = {} ---设置玩家pk值 ---@param actor 玩家对象 ---@param pkValue PK值 function pk.setpkvalue(actor, pkValue) --特定的线路不增加PK值 local mapUid = getbaseinfo(actor, "unimapid") local mapInfo = getmapinfobyid(actor, mapUid) if not table.isNullOrEmpty(mapInfo) then local mapCfgId = table.getValue(mapInfo, "cfgid") local mapLine = table.getValue(mapInfo, "line") local pkLine = ConfigDataManager.getTableValue("cfg_map_line", "pkline", "id", mapCfgId) if not string.isNullOrEmpty(pkLine) then local pkLines = string.split(pkLine, "|") for _, line in pairs(pkLines) do if tonumber(mapLine) == tonumber(line) then jprint("pk线路不增加PK值", mapUid, mapCfgId, mapLine, actor) return end end end end setplaydef(actor, PlayerDefKey.pkValue.PK_VALUE, pkValue) -- 获取附近角色,给每一个角色发送对应角色PK值变化的消息 local sendPlayerIds = {} local nearPlayers = getnarplayer(actor) if nearPlayers or #nearPlayers > 0 then for i = 1, #nearPlayers do sendPlayerIds[i] = nearPlayers[i].luaplayer end sendPlayerIds[#sendPlayerIds + 1] = actor if sendPlayerIds and #sendPlayerIds > 0 then for i = 1, #sendPlayerIds do sendluamsg(sendPlayerIds[i], LuaMessageIdToClient.PK_VALUE_CHANGE, { rid = actor, pkValue = pkValue }) end end else sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, { rid = actor, pkValue = tonumber(pk.getpkvalue(actor)) }) end end ---获取指定玩家PK值 ---@param actor 玩家对象 ---@return PK值 function pk.getpkvalue(actor) local pkValue = getplaydef(actor, PlayerDefKey.pkValue.PK_VALUE) if not pkValue then return 0 end return pkValue end ---击杀玩家处理 ---@param actor 攻击玩家对象 ---@param diePlayer 死亡玩家对象 function pk.killplayerpkvaluehandle(actor, diePlayer) if RolandSeige.IsPlayerInRoland(actor) then return end -- 清除diePlayer身上存储的防卫时间信息 setplaydef(diePlayer, PlayerDefKey.pkValue.LAST_ATTACK, {}) -- 判断是否在防卫时间内击杀的玩家,如果在防卫时间内击杀玩家则不增加PK值 local attackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK) local now = tonumber(getbaseinfo("now")) local defenseTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME) if attackInfo and next(attackInfo) then for index = 1, #attackInfo do if attackInfo[index].attackId == diePlayer then if defenseTime and now - tonumber(attackInfo[index].timeStamp) <= tonumber(defenseTime) then gameDebug.print(actor:toString() .. "在防卫时间内击杀了" .. tostring(diePlayer) .. " 不增加PK值") return end end end end -- 判断击杀的玩家是否是红名玩家,是红名玩家不增加PK值 local redNameNeed = ConfigDataManager.getTableValue("cfg_pk_count", "redNameNeed", "id", 1) local diePlayerPkValue = pk.getpkvalue(diePlayer) if redNameNeed and redNameNeed ~= "" and diePlayerPkValue and tonumber(diePlayerPkValue) >= tonumber(redNameNeed) then gameDebug.print(actor:toString() .. "击杀了红名玩家" .. tostring(diePlayer) .. " 不增加PK值") return end -- 根据配表增加PK值 local curPkValue = pk.getpkvalue(actor) if curPkValue and curPkValue ~= "" and curPkValue > 0 then local addByKill = 0 local pkCountTable = ConfigDataManager.getList("cfg_pk_count") if pkCountTable or next(pkCountTable) then local maxPkValue = 0 for i = 1, #pkCountTable do local nameColor = pkCountTable[i].namecolor local minPkValue = pk.getSplitByHash(nameColor)[1] maxPkValue = pk.getSplitByHash(nameColor)[2] if curPkValue >= tonumber(minPkValue) and curPkValue <= tonumber(maxPkValue) then addByKill = pkCountTable[i].addbykill end end if tonumber(addByKill) == 0 and tonumber(curPkValue) > tonumber(maxPkValue) then addByKill = pkCountTable[#pkCountTable].addbykill end if addByKill == 0 then addByKill = pkCountTable[1].addbykill end end pk.setpkvalue(actor, tonumber(addByKill) + tonumber(curPkValue)) else local addByKill = ConfigDataManager.getTableValue("cfg_pk_count", "addByKill", "id", 1) pk.setpkvalue(actor, addByKill) end local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1) local splitString = pk.getSplitByHash(reduceByTime) if splitString then setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1]) else gameDebug.print("killplayerpkvaluehandle cfg_pk_count表reduceByTime is null") return end end ---玩家被攻击处理 ---@param actor 玩家对象 ---@param fightParam 被攻击参数 caster:攻击者对象、target:被攻击者对象、mapid:地图id、skillid:技能id、skilllevel:技能等级、castertype:攻击者类型、targettype:被攻击者类型 function pk.underattackpkvaluehandle(actor, fightParam) -- 当玩家攻击玩家时进行后面的逻辑 if fightParam.castertype and fightParam.targettype and fightParam.castertype == 1 and fightParam.targettype == 1 then local lastAttackInfo = getplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK) if not lastAttackInfo or lastAttackInfo == "" or not next(lastAttackInfo) then -- 没有玩家攻击时间信息存入新的 local attackInfo = { attackId = fightParam.caster, timeStamp = tonumber(getbaseinfo("now")) } setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, attackInfo) else -- 有玩家攻击时间信息遍历判断是否已经存在攻击者id -- 如果存在,判断时间是否超时,如果超时存入新的时间戳 local exists = false local now = tonumber(getbaseinfo("now")) local defenseTime = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.DEFENSE_TIME) for index = 1, #lastAttackInfo do if tonumber(lastAttackInfo[index].attackId) == tonumber(fightParam.caster) then exists = true local lastTime = lastAttackInfo[index].timeStamp if defenseTime and (now - tonumber(lastTime)) > tonumber(defenseTime) then table.remove(lastAttackInfo, index) lastAttackInfo[#lastAttackInfo + 1] = { attackId = fightParam.caster, timeStamp = now } setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo) end break end end -- 如果不存在则存入 if not exists then lastAttackInfo[#lastAttackInfo + 1] = { attackId = fightParam.caster, timeStamp = tonumber(getbaseinfo("now")) } setplaydef(actor, PlayerDefKey.pkValue.LAST_ATTACK, lastAttackInfo) end end end end ---怪物击杀PK值处理 ---@param actor 玩家对象 ---@param monsterCfgId 怪物configId ---@param monsterLevel 怪物等级 function pk.killmonsterpkvaluehandle(actor, monsterCfgId, monsterLevel) local levelDiff = ConfigDataManager.getTableValue("cfg_pk_count", "levelDiff", "id", 1) local level = getbaseinfo(actor, "level") if tonumber(level) - tonumber(levelDiff) >= tonumber(monsterLevel) then return end local pkValue = pk.getpkvalue(actor) if pkValue and pkValue > 0 then local monsterType = ConfigDataManager.getTableValue("cfg_monster", "type", "id", monsterCfgId) local reduceByMonster = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByMonster", "id", 1) local time = pk.getSplitByHash(reduceByMonster) if time and next(time) then local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME) if reduceTime and reduceTime ~= "" then setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(reduceTime) + tonumber(time[tonumber(monsterType)])) else setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(time[tonumber(monsterType)])) end end end end ---角色PK值心跳 ---@param actor 玩家对象 function pk.SecondHeartPkValue(actor) local pkValue = pk.getpkvalue(actor) if pkValue and tonumber(pkValue) > 0 then local pkValueReduceTime = getplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME) if pkValueReduceTime and tonumber(pkValueReduceTime) > 0 then local reduceTime = getplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME) if reduceTime and tonumber(reduceTime) > 0 then if tonumber(reduceTime) >= tonumber(pkValueReduceTime) then setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, tonumber(reduceTime) - tonumber(pkValueReduceTime)) setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, 0) pkValueReduceTime = 0 else setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, tonumber(pkValueReduceTime) - tonumber(reduceTime)) setplaydef(actor, PlayerDefKey.pkValue.REDUCE_TIME, 0) return end else pkValueReduceTime = tonumber(pkValueReduceTime) - 5 if pkValueReduceTime > 0 then setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, pkValueReduceTime) return end end end if pkValueReduceTime and pkValueReduceTime <= 0 then local reduceByTime = ConfigDataManager.getTableValue("cfg_pk_count", "reduceByTime", "id", 1) local splitString = pk.getSplitByHash(reduceByTime) if splitString and next(splitString) then pk.setpkvalue(actor, pkValue - splitString[2]) setplaydef(actor, PlayerDefKey.pkValue.PK_REDUCE_TIME, splitString[1]) end end else return end end ---免罪符使用PK值处理 ---@param actor 玩家对象 ---@param itemConfigId 道具configId ---@param count 数量 function pk.exonerationcharmpkvaluehnadle(actor, itemConfigId, count) local value = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.EXONERATION_CHARM_MINUS_COUNT) for i = 1, tonumber(count) do if itemConfigId == ItemConfigId.EXONERATION_CHARM then if value then local pkValue = pk.getpkvalue(actor) if pkValue and pkValue > 0 then pkValue = tonumber(pkValue) - tonumber(value) if pkValue < 0 then pkValue = 0 end end pk.setpkvalue(actor, pkValue) end end end end ---角色进入视野发送玩家的PK值 ---@param actor 玩家对象 function pk.sendenterviewpkvalue(actor, targetPlayer) sendluamsg(targetPlayer, LuaMessageIdToClient.PK_VALUE_CHANGE, { rid = actor, pkValue = tonumber(pk.getpkvalue(actor)) }) sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, { rid = targetPlayer, pkValue = tonumber(pk.getpkvalue(targetPlayer)) }) sendluamsg(actor, LuaMessageIdToClient.PK_VALUE_CHANGE, { rid = actor, pkValue = tonumber(pk.getpkvalue(actor)) }) end ---获取字符串井号切割后的结果 ---@param str 原字符串 ---@return 切割后的table function pk.getSplitByHash(str) local data = string.split(str, "#") if data and next(data) then return data else return nil end end