bayuMIR/Mirserver/Mir200/Envir/QuestDiary/游戏功能/沙巴克/沙巴克攻城.lua
2026-06-13 01:07:35 +08:00

434 lines
12 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

ShabaKeOBJ = Up_BaseClass:new()
ShabaKeOBJ._name = "ShabaKeOBJ"
ShabaKeOBJ.id = { 51 }
for i, v in ipairs(ShabaKeOBJ.id or {}) do
Npc.clicknpcCfg[v] = ShabaKeOBJ
end
---============================================================
--- 配置区
---============================================================
local Cfg = {}
Cfg.palaceMapId = "0150" -- 皇宫地图ID
Cfg.shadowMapId = "d701" -- 影之道地图ID
-- 首沙奖励
Cfg.firstWarYuanbao = {
yuanbao = 10000,
gold = 100000000,
}
-- 平时奖励
Cfg.normalGold = 50000000 -- 5000w
-- 分布奖励
Cfg.reward = {}
Cfg.reward[0] = 0
Cfg.reward[1] = 90
Cfg.reward[2] = 10
Cfg._Player = {} -- 玩家数据
-- 参与条件
Cfg.minRelevel = 3 -- 最低转生
Cfg.minMinutes = 15 -- 最少在场分钟
-- 皇宫传送点4个随机点
Cfg.palacePoints = {
{ x = 7, y = 17 }, -- 皇宫传送点1个随机点
{ x = 11, y = 21 }, -- 皇宫传送点4个随机点
{ x = 18, y = 13 }, -- 皇宫传送点4个随机点
{ x = 12, y = 10 }, -- 皇宫传送点4个随机点
}
-- 沙区域传送点
Cfg.MovePoints = {
{ mapId = "3", x = 644, y = 290 }, -- 复活点
{ mapId = "3", x = 675, y = 340 }, -- 沙大门
{ mapId = "3", x = 635, y = 315 }, -- 武器店
{ mapId = "3", x = 670, y = 282 }, -- 衣服店
{ mapId = Cfg.shadowMapId, x = 34, y = 125 }, -- 影之道
}
-- 攻城日配置周几可以攻沙0=周日,1=周一...6=周六)
Cfg.warDays = { [3] = true, [6] = true } -- 周三、周六
-- 攻城时间(每天执行,回调内判断星期)
Cfg.scheduleTime = {
notice15 = "15:00:00", -- 15点提前公告
notice19 = "19:00:00", -- 19点提前公告
warStart = "20:55:00",
settle = "22:05:00", -- 22点5分结算奖励
}
ShabaKeOBJ.cfg = Cfg
---============================================================
--- 计划任务注册(插入全局表,由系统任务.lua统一注册
---============================================================
ShabaKeOBJ.Scheduled = {
[200] = {
name = "沙巴克15点预告",
time = Cfg.scheduleTime.notice15,
itype = 1,
func = "SBK_onNotice15",
param = nil,
},
[201] = {
name = "沙巴克19点预告",
time = Cfg.scheduleTime.notice19,
itype = 1,
func = "SBK_onNotice19",
param = nil,
},
[202] = {
name = "沙巴克攻城开始",
time = Cfg.scheduleTime.warStart,
itype = 1, --* 每天执行,回调内判断星期
func = "SBK_onWarStart",
param = nil,
},
[203] = {
name = "沙巴克活动结算",
time = Cfg.scheduleTime.settle,
itype = 1,
func = "SBK_onSettle",
param = nil,
},
}
---* 插入全局计划任务表
for i, v in pairs(ShabaKeOBJ.Scheduled or {}) do
table.insert(RebotOBJ.Scheduled, v)
end
---* 允许前端调用的函数
ShabaKeOBJ.allowFunc = { "move" }
---* 全服公告
local function SBK_announce(msg)
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":30}', msg))
end
---* 判断今天是否为攻沙日(合区首沙当天强制为攻沙日)
local function SBK_isTodayWarDay()
if (Sys.getint(VarCfg.Global.int.hf) > Sys.getint(VarCfg.Global.int.CastleNum)) then
return true
end
-- 正常判断星期几os.date "*t" 中 wday: 1=周日,2=周一...7=周六)
local wday = os.date("*t").wday
-- 转换为 0=周日,1=周一...6=周六 与配置对齐
local dayIndex = wday - 1
return Cfg.warDays[dayIndex] == true
end
---* 判断是否首沙
local function SBK_checkFirstWar()
local flag = Sys.getint(VarCfg.Global.int.CastleNum) or 0
return flag == 0
end
---============================================================
--- 运行时状态
---============================================================
local SBK = {}
SBK._state = function()
return castleinfo(5)
end --- 攻沙运行状态
SBK._isFirstWar = function()
return SBK_checkFirstWar()
end -- 是否首沙
SBK._doorOpen = function()
if not SBK._state then
return true
end
local t = os.date("*t")
if t.hour > 21 or (t.hour == 21 and t.min >= 58) then
return false
end
return true
end -- 城门状态
SBK._shadowOpen = function()
if not SBK._state then
return true
end
local t = os.date("*t")
-- 影之道开放时间21:30-21:50
if t.hour < 21 or (t.hour == 21 and t.min < 30) then
return false -- 21:30前关闭
end
if t.hour > 21 or (t.hour == 21 and t.min >= 50) then
return false -- 21:50后关闭
end
return true -- 21:30-21:50之间开启
end -- 影之道状态
SBK._castlemaster = function()
return castleinfo(3)
end -- 沙会长
SBK._castleName = function()
return castleinfo(2)
end -- 沙城行会名
ShabaKeOBJ.SBK = SBK
-- 基类_主窗体
function ShabaKeOBJ:main(actor, ...)
local info = { ... }
local data = {}
data.cfg = {}
data.cfg.checkFirstWar = SBK._isFirstWar()
data.cfg._castlemaster = SBK._castlemaster()
data.cfg._castleName = SBK._castleName()
data.npcid = info[1]
Message:SubLink(actor, self._name .. "_main", data)
end
---============================================================
--- 计划任务回调(全局函数,由引擎调用)
---============================================================
---* 15:00 提前公告
function SBK_onNotice15()
if not SBK_isTodayWarDay() then return end
SBK_announce("[沙巴克]今晚21:00将开启攻城战,请各行会做好准备!")
end
---* 19:00 提前公告
function SBK_onNotice19()
if not SBK_isTodayWarDay() then return end
SBK_announce("[沙巴克]攻城战将于21:00点开启,请各行会整装待发!")
end
---* 21:00 攻城开始
function SBK_onWarStart()
-- 判断今天是否攻沙日
if not SBK_isTodayWarDay() then return end
repaircastle()
addattacksabukall()
-- 全服公告
if SBK._isFirstWar() then
SBK_announce("[沙巴克]首次攻城战正式打响!皇宫大门已开启!")
else
SBK_announce("[沙巴克]攻城战正式打响!皇宫大门已开启!")
end
end
---* 22:00 结算
function SBK_onSettle()
Cfg._Player = {}
local player_list = getplayerlst(1)
for _, actor in ipairs(player_list or {}) do
local _guild = getbaseinfo(actor, ConstCfg.gbase.guild)
if _guild ~= "" then
local _time = Player.getTLint(actor, VarCfg.Player.TL.int["攻城区域计秒"])
if _time >= Cfg.minMinutes * 60 then
local _relevel = getbaseinfo(actor, ConstCfg.gbase.renew_level) or 0
if _relevel >= Cfg.minRelevel then
local _Identity = castleidentity(actor)
Cfg._Player[_Identity] = Cfg._Player[_Identity] or {}
table.insert(Cfg._Player[_Identity], actor)
-- Player.setTLint(actor, VarCfg.Player.TL.int["攻城区域计秒"], 0)
end
end
end
end
-- 确定是否为首次沙巴克攻城
local isFirstWar = SBK._isFirstWar()
local totalGold = 0
local totalYuanbao = 0
local warLabel = ""
if isFirstWar then
totalYuanbao = Cfg.firstWarYuanbao.yuanbao
totalGold = Cfg.firstWarYuanbao.gold
warLabel = "首次"
else
totalGold = Cfg.normalGold
end
local mailId = 1001 -- 沙巴克攻城奖励邮件ID
for _Identity, _player_list in pairs(Cfg._Player or {}) do
local ratio = Cfg.reward[_Identity] or 0
if ratio > 0 and #_player_list > 0 then
-- 按比例计算该身份组每人分得奖励
local perGold = math.floor(totalGold * ratio / 100 / #_player_list)
local perYuanbao = 0
if isFirstWar then
perYuanbao = math.floor(totalYuanbao * ratio / 100 / #_player_list)
end
local identityName = _Identity == 0 and "失败方" or (_Identity == 1 and "胜利方" or "沙城老大")
for _, actor in ipairs(_player_list) do
local name = getbaseinfo(actor, ConstCfg.gbase.name)
if name and name ~= "" then
-- 构建邮件附件内容: 物品名#数量#绑定标记
local rewards = ""
if isFirstWar and perYuanbao > 0 then
rewards = "绑定元宝#" .. perYuanbao .. "#0"
end
if perGold > 0 then
if rewards ~= "" then
rewards = rewards .. "&"
end
rewards = rewards .. "绑定金币#" .. perGold .. "#0"
end
if rewards ~= "" then
local title = "沙巴克攻城奖励"
local memo
if _Identity == 0 then
memo = string.format("您在%s沙巴克攻城战中作为%s参与获得以下参与奖励", warLabel, identityName)
else
memo = string.format("恭喜您在%s沙巴克攻城战中作为%s获得以下奖励", warLabel, identityName)
end
sendmail("#" .. name, mailId, title, memo, rewards)
end
end
end
end
end
end
---* 皇宫门及侧门关闭,进入连接点出发
function ShabaKeOBJ.onbeforeroute(actor, mapId, x, y, info)
if not SBK._state() then
return
end
if not SBK._doorOpen() and mapId == Cfg.palaceMapId then
Func.sendmsg9(actor, "[沙巴克]:#70|皇宫已关闭,禁止进入!")
info.bool = false
end
end
GameEvent.add(EventCfg.onbeforeroute, ShabaKeOBJ.onbeforeroute, ShabaKeOBJ)
---============================================================
--- 影之道传送入口
---============================================================
function ShabaKeOBJ:shadowTransfer(actor)
-- 取消非攻城时间限制,只检查影之道开放时间
if not SBK._shadowOpen() then
Func.sendmsg9(actor, "[沙巴克]:#70|影之道传送已关闭!开放时间:21:30-21:50")
return
end
local relevel = getbaseinfo(actor, ConstCfg.gbase.renew_level) or 0
if relevel < Cfg.minRelevel then
Func.sendmsg9(actor, string.format("[沙巴克]:#70|需要%d转以上才能进入!", Cfg.minRelevel))
return
end
-- 随机传送到皇宫4点之一
local idx = math.random(1, #Cfg.palacePoints)
local pt = Cfg.palacePoints[idx]
mapmove(actor, Cfg.palaceMapId, pt.x, pt.y, 3, 0)
end
function ShabaKeOBJ:move(actor, p1, p2, p3, data)
local id = data[1]
-- 取消非攻城时间限制,允许随时传送
local cfg = Cfg.MovePoints[id]
if not cfg then
return
end
if id == 5 then
if not SBK._shadowOpen() then
Func.sendmsg9(actor, "[沙巴克]:#70|影之道传送未开启!")
return
end
end
mapmove(actor, cfg.mapId, cfg.x, cfg.y, 3, 0)
end
---* 攻城开始时触发
function castlewarstart(sys)
if not iskuafuserver() then
Sys.addint(VarCfg.Global.int.CastleNum, 1)
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":30}', "[攻沙通知]沙巴克攻城已经开始!"))
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":60}', "[攻沙通知]沙巴克攻城已经开始!"))
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":90}', "[攻沙通知]沙巴克攻城已经开始!"))
end
local player_list = getplayerlst(1)
for _, actor in ipairs(player_list or {}) do
if not hastimerex(VarCfg.Timer["攻沙定时器"]) then
setontimer(actor, VarCfg.Timer["攻沙定时器"], 1)
end
end
end
---* 攻城结束时触发
function castlewarend()
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":30}', "[攻沙通知]沙巴克攻城已经结束!"))
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":60}', "[攻沙通知]沙巴克攻城已经结束!"))
sendmsg(-1, 2, string.format('{"Msg":"%s","FColor":251,"BColor":0,"Type":5,"Y":90}', "[攻沙通知]沙巴克攻城已经结束!"))
local player_list = getplayerlst(1)
for _, actor in ipairs(player_list or {}) do
if hastimerex(VarCfg.Timer["攻沙定时器"]) then
setofftimer(actor, VarCfg.Timer["攻沙定时器"])
end
end
end
---============================================================
--- 事件处理
---============================================================
---* 人物登陆 沙巴克期间计时
GameEvent.add(EventCfg.onLogin, function(actor)
if ShabaKeOBJ.SBK._state() then
if not hastimerex(VarCfg.Timer["攻沙定时器"]) then
setontimer(actor, VarCfg.Timer["攻沙定时器"], 1)
end
end
end, ShabaKeOBJ)
return ShabaKeOBJ