Player.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. ---
  2. --- Generated by EmmyLua(https://github.com/EmmyLua)
  3. --- Created by zhoutao.
  4. --- DateTime: 2024/10/28 14:17
  5. ---
  6. Player = {}
  7. local filename = "Player"
  8. local db_world_level = "R$_world_level" -- 世界等级关键字
  9. local db_player_new_get_gold = "R$_player_new_get_gold" -- 新账号的第一个角色给金币
  10. Player.Const = {
  11. player_new_get_gold = 500000
  12. }
  13. local db_gold_count = "J$_gold_count" -- 每日获得金币限制
  14. --- 改变角色名称
  15. --- @param actor table 玩家对象
  16. --- @param msgData table 角色名称
  17. function Player.changeRoleName(actor, msgData)
  18. local roleName = msgData["roleName"]
  19. -- 首次改名不再免费
  20. -- local isFirstChangeName = getplaydef(actor, PlayerDefKey.player.FIRST_CHANGE_NAME)
  21. -- if not string.isNullOrEmpty(isFirstChangeName) then
  22. local value = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.CHANGE_NAME_CARD_COST)
  23. local split = string.split(value, "|")
  24. local tmps = string.split(split[2], "#")
  25. local costItemId = tmps[1]
  26. local costCount = tmps[2]
  27. if not Bag.checkItem(actor, costItemId, costCount) then
  28. noticeTip.noticeinfo(actor, StringIdConst.TEXT346)
  29. return
  30. end
  31. if not checkrolename(actor, roleName) then
  32. jprint("角色名不合法 actor:" .. actor:toString() .. " roleName:" .. roleName)
  33. return
  34. end
  35. -- 从背包中移除指定数量的道具
  36. removeitemfrombag(actor, costItemId, costCount, 0, 9999, "角色改名")
  37. changerolename(actor, roleName)
  38. return
  39. -- else
  40. -- if not checkrolename(actor, roleName) then
  41. -- jprint("角色名不合法 actor:" .. actor:toString() .. " roleName:" .. roleName)
  42. -- return
  43. -- end
  44. -- changerolename(actor, roleName)
  45. -- setplaydef(actor, PlayerDefKey.player.FIRST_CHANGE_NAME, 1)
  46. -- end
  47. end
  48. --- 获取角色是否为首次改名
  49. --- @param actor table 玩家对象
  50. function Player.getRoleChangeNameInfo(actor)
  51. -- local isFirstChangeName = getplaydef(actor, PlayerDefKey.player.FIRST_CHANGE_NAME)
  52. -- sendluamsg(actor, LuaMessageIdToClient.RES_ROLE_IS_FIRST_CHANGE_NAME, isFirstChangeName and 1 or 0)
  53. -- 首次改名不再免费
  54. sendluamsg(actor, LuaMessageIdToClient.RES_ROLE_IS_FIRST_CHANGE_NAME, 1)
  55. end
  56. function Player.UpdateFightValue(actor)
  57. --默认战斗力=10*攻击+8*防御+0.25*生命+1400*1%卓越一击倍率+1160*1%幸运一击倍率+4670*1%双倍一击倍率+3400*1%攻速+3400*1%伤害加成
  58. local maxDC = getattrinfo(actor, "maxDC")
  59. local armor = getattrinfo(actor, "armor")
  60. local maxHP = getattrinfo(actor, "maxHP")
  61. local excellentDamageChance = math.max(getattrinfo(actor, "excellentDamageChance"), 1)
  62. local criticalDamageChance = math.max(getattrinfo(actor, "criticalDamageChance"), 1)
  63. local doubleDamageChance = math.max(getattrinfo(actor, "doubleDamageChance"), 1)
  64. local attackSpeed = math.max(getattrinfo(actor, "attackSpeed"), 1)
  65. local damageRate = math.max(getattrinfo(actor, "damageRate"), 1)
  66. local result =
  67. 10 * maxDC + 8 * armor + 0.25 * maxHP + 1400 * excellentDamageChance * 0.01 + 1160 * criticalDamageChance * 0.01 +
  68. 4670 * doubleDamageChance * 0.01 +
  69. 3400 * attackSpeed * 0.01 +
  70. 3400 * damageRate * 0.01
  71. savefightvalue(actor, result)
  72. end
  73. -- 内置经验只有泡点和杀怪有经验加成
  74. -- 这个方法复刻内置经验加成计算,用来计算实际加成后的经验
  75. -- 仅直接发经验奖励可调用,地图经验衰减,怪物衰减在这不适用
  76. function Player.calculExpByAddRate(actor, originExp)
  77. local finalExp = originExp
  78. finalExp = Player.applyExpModification(actor, finalExp, 19, true)
  79. finalExp = Player.applyExpModification(actor, finalExp, 20, false)
  80. finalExp = finalExp * TripleIncome.GetRate(actor)
  81. -- 应用线路经验倍率
  82. finalExp = LineManager.applyExpRate(actor, finalExp)
  83. return finalExp
  84. end
  85. function Player.applyExpModification(actor, exp, type, isAdd)
  86. local tableList = ConfigDataManager.getTable("cfg_att_special", "type", type)
  87. for _, t in pairs(tableList) do
  88. local attrId = tonumber(t.id)
  89. local attrName = attrid2name(actor, attrId)
  90. local attrValue = getattrinfo(actor, attrName)
  91. if isAdd then
  92. exp = attrValue * exp + exp
  93. else
  94. exp = exp - attrValue * exp
  95. end
  96. end
  97. return exp
  98. end
  99. function Player.calWorldLevelExpRate(actor)
  100. local roleLevel = getbaseinfo(actor, "level")
  101. local worldLevel = getsysvar(actor, db_world_level) or 0
  102. local levelDistance = math.floor((worldLevel - roleLevel) / 10.0)
  103. -- info("Player.calWorldLevelExpRate levelDistance:" .. levelDistance .. " 角色等级:" .. roleLevel .. " 世界等级:" .. worldLevel)
  104. if levelDistance > 10 then
  105. return 200
  106. elseif levelDistance > 0 then
  107. return levelDistance * 20
  108. end
  109. return 0
  110. end
  111. function Player.calWorldLevel()
  112. local roles = getallrolesummaryinfos()
  113. local allRoles = {}
  114. if roles then
  115. for _, role in ipairs(roles) do
  116. local actor = role["actor"]
  117. local buidRole = Player.buildOneRole(actor)
  118. table.insert(allRoles, buidRole)
  119. end
  120. table.sort(
  121. allRoles,
  122. function(a, b)
  123. if a.level == b.level then
  124. return a.rid > b.rid
  125. else
  126. return a.level > b.level
  127. end
  128. end
  129. )
  130. local levelNum = 0
  131. local levelCount = 0
  132. for i = 1, 10 do
  133. if #allRoles < i then
  134. break
  135. end
  136. levelNum = levelNum + allRoles[i].level
  137. levelCount = levelCount + 1
  138. end
  139. -- info("Player.calWorldLevel levelNum:" .. levelNum .. " levelCount:" .. levelCount)
  140. return math.floor(levelNum / levelCount)
  141. end
  142. return 0
  143. end
  144. function Player.buildOneRole(actor)
  145. local role = {}
  146. role["actor"] = actor
  147. role["rid"] = getbaseinfo(actor, "id")
  148. role["level"] = getbaseinfo(actor, "level")
  149. return role
  150. end
  151. function Player.updateWorldLevel(actor, needForceSendMsg)
  152. --获取玩家数据,并更新世界等级
  153. local data = getplayermaininfo(actor)
  154. local playerLevel = 0
  155. if data ~= nil and data.level ~= nil then
  156. playerLevel = data.level
  157. end
  158. local worldLevel = getsysvar(actor, db_world_level) or 0
  159. -- if data ~= nil and data.level ~= nil then
  160. -- 更新世界等级,世界等级计算按照服务器前50名的平均等级计算
  161. if worldLevel < playerLevel then
  162. local newWorldLevel = Player.calWorldLevel()
  163. setsysvar(actor, db_world_level, newWorldLevel)
  164. if newWorldLevel < playerLevel then
  165. local allPlayer = getallplayer(actor)
  166. if allPlayer ~= nil then
  167. for i = 1, #allPlayer do
  168. local player = getactor(actor, allPlayer[i])
  169. sendluamsg(player, LuaMessageIdToClient.RES_ROLE_INFO, {newWorldLevel})
  170. local expRate = Player.calWorldLevelExpRate(actor) * 100
  171. ExpBonus.changeBonus(actor, BonusType.WORLD_LEVEL_EXP_BONUS, expRate, 0, 0)
  172. end
  173. end
  174. return
  175. end
  176. -- end
  177. end
  178. if needForceSendMsg then
  179. sendluamsg(actor, LuaMessageIdToClient.RES_ROLE_INFO, {worldLevel})
  180. local expRate = Player.calWorldLevelExpRate(actor) * 100
  181. ExpBonus.changeBonus(actor, BonusType.WORLD_LEVEL_EXP_BONUS, expRate, 0, 0)
  182. end
  183. end
  184. function Player.updateTotalCharge(actor)
  185. local totalChargeNum = RechargeRecord.getTotalMoney(actor)
  186. sendluamsg(actor, LuaMessageIdToClient.RES_PLAYER_TOTAL_CHARGE_INFO, {total_charge = totalChargeNum})
  187. end
  188. function Player.newPlayerGetGold(actor)
  189. local uid = getbaseinfo(actor, "uid")
  190. local isNewPlayerForGold = getsysvar(db_player_new_get_gold .. uid) or 0
  191. if isNewPlayerForGold <= 0 then
  192. Bag.addItemToBag(actor, 10010001, Player.Const.player_new_get_gold, 0, 9999, "新账号金币福利")
  193. setsysvar(actor, db_player_new_get_gold .. uid, 1)
  194. sendluamsg(actor, LuaMessageIdToClient.RES_NEW_PLAYER_FOR_GOLD, {})
  195. return
  196. end
  197. -- sendluamsg(actor, LuaMessageIdToClient.RES_NEW_PLAYER_FOR_GOLD, {})
  198. end
  199. function Player.updateLoginInfo(actor)
  200. --获取玩家数据,并更新世界等级
  201. Player.updateWorldLevel(actor, true)
  202. end
  203. function Player.onLoginEnd(actor)
  204. --获取玩家数据,并更新世界等级
  205. Player.updateWorldLevel(actor, false)
  206. Player.newPlayerGetGold(actor)
  207. -- Player.updateCurrency(actor)
  208. callonserial(actor, "_updatecurrency")
  209. Player.updateTotalCharge(actor)
  210. end
  211. function Player.onLevelUp(actor)
  212. --获取玩家数据,并更新世界等级
  213. Player.updateWorldLevel(actor, true)
  214. end
  215. function Player.enterMap(actor)
  216. --获取玩家数据,并更新世界等级
  217. Player.updateWorldLevel(actor, true)
  218. end
  219. -- 记录累充奖励
  220. function Player.rechargeEvent(actor, cfg_recharge, count, amount, ext, outRewards)
  221. Player.updateTotalCharge(actor)
  222. end
  223. -- 更新货币数据
  224. -- function Player.updateCurrency(actor)
  225. function _updatecurrency(actor)
  226. local uid = getbaseinfo(actor, "uid")
  227. local mData = getsysvar(actor, "R$MoneyData_" .. uid)
  228. if mData == nil then
  229. mData = {}
  230. local ListInfo = getrolelist(actor, uid)
  231. for _, roleInfo in pairs(ListInfo) do
  232. local rid = roleInfo["id"]
  233. local player = getactor(rid)
  234. for _, cfgId in pairs({10010001, 10020001, 10040001, 10050001}) do
  235. local num = getbagitemcountbyid(player, cfgId) or 0
  236. mData[cfgId] = num + (mData[cfgId] or 0)
  237. end
  238. end
  239. setsysvar(actor, "R$MoneyData_" .. uid, mData)
  240. end
  241. for cfgId, count in pairs(mData) do
  242. local num = getbagitemcountbyid(actor, cfgId) or 0
  243. if num ~= count then
  244. -- info("Player.updateCurrency-> ", actor, cfgId, num, count)
  245. local diff = count - num
  246. if diff > 0 then
  247. Bag.addItemToBag(actor, cfgId, diff, 0, 9999, "货币数据同步补偿")
  248. elseif diff < 0 then
  249. removeitemfrombag(actor, cfgId, -diff, 0, 9999, "货币数据同步扣除")
  250. end
  251. end
  252. end
  253. end
  254. function Player.GoldCountAdd(actor, num)
  255. if num <= 0 then
  256. return
  257. end
  258. local gold_count = getplaydef(actor, db_gold_count) or 0
  259. setplaydef(actor, db_gold_count, gold_count + num)
  260. Player.ResGoldCountToday(actor)
  261. end
  262. function Player.GoldCountEnough(actor, num)
  263. if num < 0 then
  264. return false, 0
  265. end
  266. local level = getbaseinfo(actor, "level")
  267. local gold_count = getplaydef(actor, db_gold_count) or 0
  268. local config_gold_count = ConfigDataManager.getById("cfg_gold_day_add", level)
  269. if config_gold_count == nil then
  270. return false, 0
  271. end
  272. local gold_max = tonumber(config_gold_count.gold_num)
  273. if gold_count >= gold_max then
  274. return false, 0
  275. end
  276. if gold_max - gold_count >= num then
  277. return true, num
  278. end
  279. return true, gold_max - gold_count
  280. end
  281. function Player.ResGoldCountToday(actor)
  282. local gold_count = getplaydef(actor, db_gold_count) or 0
  283. sendluamsg(actor, LuaMessageIdToClient.RES_GOLD_COUNT_TODAY, {gold_num = gold_count})
  284. end
  285. function Player.ResetGoldCount(actor)
  286. setplaydef(actor, db_gold_count, 0)
  287. Player.ResGoldCountToday(actor)
  288. end
  289. function Player.pickUpItem(actor, items)
  290. local datas = {}
  291. for _, item in pairs(items) do
  292. if item["cfgid"] == 10010001 then
  293. local enough, left_num = Player.GoldCountEnough(actor, item["count"])
  294. if enough then
  295. datas[item["id"]] = {allow = true, count = left_num}
  296. Player.GoldCountAdd(actor, left_num)
  297. else
  298. datas[item["id"]] = {allow = false}
  299. end
  300. return datas
  301. end
  302. end
  303. return nil
  304. end
  305. -- ------------------------------------------------------------- --
  306. --TODO 一定要放到文件最后
  307. -- 注册登录事件
  308. RechargeEventListerTable:eventLister("0", "充值", Player.rechargeEvent)