BiHu.lua 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. BiHu = {}
  2. local this = {}
  3. -- 庇护系统相关常量
  4. local BIHU_BUFF_ID = 104001 -- 庇护BUFF ID
  5. local BIHU_COST_TYPE = 10040001 -- 每小时消耗类型
  6. local BIHU_COST_PER_HOUR = 20 -- 每小时消耗数量
  7. local BIHU_TIME_START_HOUR = 23 -- 庇护开始时间(23点)
  8. local BIHU_TIME_END_HOUR = 8 -- 庇护结束时间(8点)
  9. local BIHU_DURATION = 3600 -- 持续时间3600秒(1小时)
  10. -- 检查当前时间是否在庇护时间段内(23:00-8:00)
  11. function BiHu.isBiHuTime()
  12. local h = TimeUtil.GetTodayHour()
  13. -- 23点到8点之间为庇护时间
  14. return h >= BIHU_TIME_START_HOUR or h < BIHU_TIME_END_HOUR
  15. end
  16. -- 判断玩家是否有庇护
  17. function BiHu.isBiHu(actor)
  18. local data = API.GetTable(actor, "BIHU_DATA_INFO") or {}
  19. return data.isActive == true
  20. end
  21. -- 处理庇护开启/关闭
  22. -- @param actor 玩家对象
  23. -- @param msgData 消息数据 {type: 0开启, 1关闭, 2续费, 3BOSS移除}
  24. function BiHu.HandleBiHu(actor, msgData)
  25. local type = msgData.type or 0 --0 开启,1 关闭,2 续费,3 BOSS移除
  26. local data = API.GetTable(actor, "BIHU_DATA_INFO") or {}
  27. local cfgNum = BIHU_COST_PER_HOUR --tonumber(ConfigDataManager.getTableValue("cfg_global", "value", "id", 260005) or "20")
  28. -- 开启庇护(type == 0)
  29. if type == 0 then
  30. -- 如果已经有庇护,提示
  31. if data.isActive then
  32. tipinfo(actor, "庇护已开启,请勿重复开启")
  33. return false
  34. end
  35. -- 扣除首次钻石
  36. local result = removeitemfrombag(actor, BIHU_COST_TYPE, cfgNum, 0, 9999, '庇护消耗')
  37. if not result then
  38. tipinfo(actor, "钻石不足,无法开启庇护")
  39. return false
  40. end
  41. -- 检查时间
  42. if not BiHu.isBiHuTime() then
  43. tipinfo(actor, "当前时间不在庇护时间段内(23:00-8:00)")
  44. return false
  45. end
  46. -- 开启庇护
  47. local nowsec = getbaseinfo("nowsec")
  48. data.isActive = true
  49. data.startTime = nowsec
  50. data.lastChargeTime = nowsec
  51. data.totalCost = cfgNum
  52. data.chargeCount = 1 -- 扣费次数
  53. -- 强制和平模式
  54. setplayersetting(actor, 1, 1) -- 1 和平 5战盟
  55. API.SetTable(actor, "BIHU_DATA_INFO", data)
  56. BiHu.SendBiHuInfo(actor, data)
  57. buffer(actor, BIHU_BUFF_ID)
  58. -- tipinfo(actor, "庇护已开启!每小时消耗" .. cfgNum .. "钻石")
  59. jprint("=== 庇护开启 ===", actor, getbaseinfo(actor, "maptitle"), "时间:", data.startTime)
  60. return true
  61. -- 关闭庇护(type == 1)
  62. elseif type == 1 then
  63. if not data.isActive then
  64. tipinfo(actor, "当前未开启庇护")
  65. return false
  66. end
  67. BiHu.EndBiHu(actor, "手动关闭")
  68. return true
  69. -- 续费(type == 2)- 定时调用
  70. elseif type == 2 then
  71. if not data.isActive then
  72. return false
  73. end
  74. -- 扣除钻石
  75. local result = removeitemfrombag(actor, 10040001, cfgNum, 0, 9999, '庇护续费')
  76. if not result then
  77. BiHu.EndBiHu(actor, "钻石不足")
  78. return false
  79. end
  80. -- 更新数据
  81. data.lastChargeTime = getbaseinfo("nowsec")
  82. data.totalCost = (data.totalCost or 0) + cfgNum
  83. data.chargeCount = (data.chargeCount or 0) + 1
  84. API.SetTable(actor, "BIHU_DATA_INFO", data)
  85. BiHu.SendBiHuInfo(actor, data)
  86. jprint("=== 庇护续费 ===", actor, "第" .. data.chargeCount .. "次扣费", "总消耗:", data.totalCost)
  87. return true
  88. -- BOSS移除(type == 3)
  89. elseif type == 3 then
  90. if data.isActive then
  91. BiHu.EndBiHu(actor, "选定BOSS")
  92. end
  93. return true
  94. elseif type == -1 then
  95. -- 仅发送信息
  96. BiHu.SendBiHuInfo(actor, data)
  97. return true
  98. end
  99. return false
  100. end
  101. -- 结束庇护(内部调用)
  102. -- @param actor 玩家对象
  103. -- @param reason 结束原因
  104. function BiHu.EndBiHu(actor, reason)
  105. local data = API.GetTable(actor, "BIHU_DATA_INFO") or {}
  106. if not data.isActive then
  107. return false
  108. end
  109. -- 计算庇护时间和消耗
  110. local nowsec = getbaseinfo("nowsec")
  111. local totalSeconds = nowsec - (data.startTime or nowsec)
  112. local totalCost = data.totalCost or 0
  113. local chargeCount = data.chargeCount or 0
  114. -- 清除数据
  115. data = {}
  116. API.SetTable(actor, "BIHU_DATA_INFO", data)
  117. BiHu.SendBiHuInfo(actor,data)
  118. -- 发送结束提示
  119. local title = "庇护结束"
  120. local str = "%s 庇护系统已结束!\n总庇护时间:%s\n总消耗钻石:%d\n扣费次数:%d次"
  121. local content = string.format(str, reason, BiHu.formatSecondsToHourMinute(totalSeconds), totalCost, chargeCount)
  122. sendluamsg(actor, LuaMessageIdToClient.COMMON_TIPS_PANEL, {title = title, content = content})
  123. delbuff(actor, BIHU_BUFF_ID)
  124. jprint("=== 庇护结束 ===", actor, getbaseinfo(actor, "maptitle"), reason, totalSeconds, totalCost)
  125. return true
  126. end
  127. -- 定时检查庇护(每分钟调用一次)
  128. -- @param actor 玩家对象
  129. function BiHu.onHourCheck(actor)
  130. -- 检查是否有庇护
  131. local data = API.GetTable(actor, "BIHU_DATA_INFO") or {}
  132. if not data.isActive then
  133. return
  134. end
  135. -- 检查时间
  136. if not BiHu.isBiHuTime() then
  137. BiHu.EndBiHu(actor, "庇护时间结束")
  138. return
  139. end
  140. local nowsec = getbaseinfo("nowsec")
  141. local lastChargeTime = data.lastChargeTime or data.startTime or nowsec
  142. -- 计算从上次扣费到现在的秒数
  143. local elapsedSeconds = nowsec - lastChargeTime
  144. -- 判断当前一小时是否到期(>= 3600秒)且 不在安全区
  145. if elapsedSeconds >= BIHU_DURATION then
  146. if insafezone(actor) then
  147. BiHu.EndBiHu(actor, "安全区内不自动续费")
  148. else
  149. -- 条件满足,自动续费
  150. BiHu.HandleBiHu(actor, {type = 2})
  151. end
  152. end
  153. end
  154. -- 检查玩家是否可以切换模式
  155. -- @param actor 玩家对象
  156. -- @param newMode 新模式
  157. -- @return boolean 是否允许切换
  158. function BiHu.checkCanChangeMode(actor, newMode)
  159. -- 如果没有庇护,允许切换
  160. if not BiHu.isBiHu(actor) then
  161. -- 执行模式切换
  162. if newMode == 1 then
  163. setplayersetting(actor, 1, 1) -- 和平
  164. elseif newMode == 5 then
  165. setplayersetting(actor, 1, 5) -- 战盟
  166. else
  167. setplayersetting(actor, 1, newMode)
  168. end
  169. return true
  170. end
  171. -- 有庇护,提示并拒绝
  172. tipinfo(actor, "当前开启庇护状态,无法切换模式。请先关闭庇护系统。")
  173. return false
  174. end
  175. -- 发送庇护信息给客户端
  176. -- @param actor 玩家对象
  177. function BiHu.SendBiHuInfo(actor, data)
  178. data = data or API.GetTable(actor, "BIHU_DATA_INFO") or {}
  179. local msgData = {
  180. isActive = data.isActive or false,
  181. startTime = data.startTime or 0,
  182. lastChargeTime = data.lastChargeTime or 0,
  183. -- totalCost = data.totalCost or 0,
  184. -- chargeCount = data.chargeCount or 0,
  185. -- currentTime = getbaseinfo("nowsec"), -- 当前时间戳
  186. -- isInBiHuTime = BiHu.isBiHuTime(), -- 是否在庇护时间段
  187. -- costPerHour = tonumber(ConfigDataManager.getTableValue("cfg_global", "value", "id", 260005) or "20")
  188. }
  189. if msgData.isActive then
  190. if not hasbuff(actor, BIHU_BUFF_ID) then
  191. buffer(actor, BIHU_BUFF_ID)
  192. end
  193. msgData.endTime = msgData.lastChargeTime + BIHU_DURATION -- 庇护结束时间
  194. end
  195. sendluamsg(actor, LuaMessageIdToClient.RES_BIHU_MsgID, msgData)
  196. end
  197. -- 秒数转换为"X时Y分Z秒"格式
  198. -- @param seconds number 秒数
  199. -- @return string 格式化时间字符串(如:"1时5分30秒"、"0时10分0秒")
  200. function BiHu.formatSecondsToHourMinute(seconds)
  201. if not seconds or seconds <= 0 then
  202. return "0时0分0秒"
  203. end
  204. local hours = math.floor(seconds / 3600)
  205. local minutes = math.floor((seconds % 3600) / 60)
  206. local remainingSeconds = seconds % 60
  207. return string.format("%d时%d分%d秒", hours, minutes, remainingSeconds)
  208. end