为了Lua模块化设计现开始设计通用函数,加了详细注释及使用范例,力求情怀站的Lua代码更简洁可读。

查询物品携带数量函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 查询物品携带数量的函数,类似TinTin++的carryqty
-- 参数说明:
-- item_id: 物品ID,如"da huandan"
-- 返回值:物品数量,如果没有则返回0
function carryqty(item_id)
-- 如果参数为空,返回0
if not item_id or item_id == "" then
return 0
end

-- 如果物品表中没有该物品,返回0
if not item or not item[item_id] then
return 0
end

-- 返回物品数量
return item[item_id]
end

通用触发器管理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
-- 通用触发器管理函数
-- trigger_prefix: 触发器名称前缀
-- start_index: 开始索引
-- end_index: 结束索引
function manage_triggers(trigger_prefix, start_index, end_index, action)
for i = start_index, end_index do
if action == "close" then
close_trigger(trigger_prefix .. "_" .. i)
elseif action == "open" then
open_trigger(trigger_prefix .. "_" .. i)
elseif action == "delete" then
del_trigger(trigger_prefix .. "_" .. i)
end
end
end

-- 关闭指定前缀和范围的触发器
function close_triggers(trigger_prefix, start_index, end_index)
manage_triggers(trigger_prefix, start_index, end_index, "close")
end

-- 打开指定前缀和范围的触发器
function open_triggers(trigger_prefix, start_index, end_index)
manage_triggers(trigger_prefix, start_index, end_index, "open")
end

-- 删除指定前缀和范围的触发器
function delete_triggers(trigger_prefix, start_index, end_index)
manage_triggers(trigger_prefix, start_index, end_index, "delete")
end

-- 管理零散索引的触发器
-- trigger_prefix: 触发器名称前缀
-- indices: 索引表,如 {1, 3, 6, 11, 12}
-- action: 操作类型,"close", "open" 或 "delete"
function manage_scattered_triggers(trigger_prefix, indices, action)
for _, i in ipairs(indices) do
if action == "close" then
close_trigger(trigger_prefix .. "_" .. i)
elseif action == "open" then
open_trigger(trigger_prefix .. "_" .. i)
elseif action == "delete" then
delete_triggers(trigger_prefix .. "_" .. i)
end
end
end

-- 关闭指定前缀和零散索引的触发器
function close_scattered_triggers(trigger_prefix, indices)
manage_scattered_triggers(trigger_prefix, indices, "close")
end

-- 打开指定前缀和零散索引的触发器
function open_scattered_triggers(trigger_prefix, indices)
manage_scattered_triggers(trigger_prefix, indices, "open")
end

-- 删除指定前缀和零散索引的触发器
function delete_scattered_triggers(trigger_prefix, indices)
manage_scattered_triggers(trigger_prefix, indices, "delete")
end

--用法示例:
--[[
-- 关闭otherquest_task_1到otherquest_task_5的触发器
close_triggers("otherquest_task", 1, 5)

-- 打开fight_1到fight_10的触发器
open_triggers("fight", 1, 10)

-- 删除quest_1到quest_3的触发器
delete_triggers("quest", 1, 3)

-- 关闭fight_1, fight_3, fight_6, fight_11, fight_12的触发器
close_scattered_triggers("fight", {1, 3, 6, 11, 12})

-- 打开otherquest_task_2, otherquest_task_5, otherquest_task_8的触发器
open_scattered_triggers("otherquest_task", {2, 5, 8})

-- 删除quest_1, quest_4, quest_7的触发器
delete_scattered_triggers("quest", {1, 4, 7})
--]]

通用A*寻路算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
-- 通用A*寻路算法
-- start_room: 起始房间ID
-- end_room: 目标房间ID
-- options: 可选参数表,包含以下可选项:
-- - room_list: 可用房间列表,默认为nil(使用所有房间)
-- - heuristic_func: 启发式函数,默认为曼哈顿距离
-- - get_neighbors_func: 获取相邻房间函数,默认使用exits表
-- - cost_func: 计算移动成本函数,默认为1
-- - max_iterations: 最大迭代次数,默认为10000
-- - debug: 是否输出调试信息,默认为false
-- 添加通用A*寻路算法
function astar_search(start_room, end_room, options)
options = options or {}
local room_list = options.room_list
local max_iterations = options.max_iterations or 10000
local debug = options.debug or false
local max_radius = options.max_radius or 5 -- 最大搜索半径参数,默认5

-- 默认启发式函数:曼哈顿距离
local function default_heuristic(room_id, goal_id)
if not rooms[room_id] or not rooms[goal_id] then
return 999999 -- 如果房间不存在,返回一个很大的值
end

local x1, y1 = rooms[room_id].x or 0, rooms[room_id].y or 0
local x2, y2 = rooms[goal_id].x or 0, rooms[goal_id].y or 0

local distance = math.abs(x1 - x2) + math.abs(y1 - y2)

-- 如果距离超过最大半径,返回一个很大的值
if distance > max_radius then
return 999999
end

return distance
end

-- 默认获取相邻房间函数
local function default_get_neighbors(room_id)
local neighbors = {}
if not rooms[room_id] or not rooms[room_id].exits then
return neighbors
end

for dir, next_room in pairs(rooms[room_id].exits) do
-- 如果提供了房间列表,则只考虑列表中的房间
if not room_list or table.contains(room_list, next_room) then
table.insert(neighbors, { room = next_room, dir = dir, cost = 1 })
end
end

return neighbors
end

-- 检查表中是否包含某个值
local function table_contains(t, value)
for _, v in pairs(t) do
if v == value then
return true
end
end
return false
end

-- 使用自定义或默认函数
local heuristic = options.heuristic_func or default_heuristic
local get_neighbors = options.get_neighbors_func or default_get_neighbors

-- 优先队列实现
local open_set = {}
local closed_set = {}
local g_score = {} -- 从起点到当前点的实际代价
local f_score = {} -- 估计总代价
local came_from = {} -- 记录路径
local directions = {} -- 记录方向

-- 初始化起点
g_score[start_room] = 0
f_score[start_room] = heuristic(start_room, end_room)
table.insert(open_set, start_room)

local iterations = 0

while #open_set > 0 and iterations < max_iterations do
iterations = iterations + 1

-- 找到open_set中f_score最小的节点
local current_index = 1
for i = 2, #open_set do
if f_score[open_set[i]] < f_score[open_set[current_index]] then
current_index = i
end
end

local current = open_set[current_index]

-- 如果到达目标,构建路径并返回
if current == end_room then
local path = { current }
local path_dirs = {}

while came_from[current] do
current = came_from[current]
table.insert(path, 1, current)
if directions[current] then
table.insert(path_dirs, 1, directions[current])
end
end

if debug then
echo("\nA*搜索完成,迭代次数: " .. iterations)
echo("\n路径: " .. table.concat(path, " -> "))
echo("\n方向: " .. table.concat(path_dirs, ", "))
end

return path, path_dirs
end

-- 从open_set中移除当前节点
table.remove(open_set, current_index)
-- 添加到closed_set
table.insert(closed_set, current)

-- 检查所有邻居
for _, neighbor_info in ipairs(get_neighbors(current)) do
local neighbor = neighbor_info.room
local dir = neighbor_info.dir
local move_cost = neighbor_info.cost or 1

-- 如果邻居已经在closed_set中,跳过
if not table_contains(closed_set, neighbor) then
-- 计算从起点经过当前节点到邻居的代价
local tentative_g_score = (g_score[current] or 0) + move_cost

-- 如果邻居不在open_set中,或者找到了更好的路径
if not table_contains(open_set, neighbor) or tentative_g_score < (g_score[neighbor] or math.huge) then
-- 更新路径信息
came_from[neighbor] = current
directions[neighbor] = dir
g_score[neighbor] = tentative_g_score
f_score[neighbor] = tentative_g_score + heuristic(neighbor, end_room)

-- 如果邻居不在open_set中,添加它
if not table_contains(open_set, neighbor) then
table.insert(open_set, neighbor)
end
end
end
end
end

if debug then
echo("\nA*搜索失败,迭代次数: " .. iterations)
end

-- 没有找到路径
return nil, nil
end

-- 使用A*寻路和job.lua中的get_job_rooms函数寻找最佳任务路径
-- start_room: 起始房间ID
-- job_zone: 任务区域
-- flag_job: 任务标志
-- options: 可选参数表,与astar_search相同
function find_best_job_path(start_room, job_zone, flag_job, options)
options = options or {}

-- 获取任务房间列表
local room_list_check = {}
for _, room_id in ipairs(get_job_rooms(job_zone, flag_job) or {}) do
room_list_check[room_id] = true
end

-- 重置搜索列表
local search_list = reset_search_list(room_list_check, get_job_rooms(job_zone, flag_job), job_zone, flag_job, 1)

if #search_list == 0 then
if options.debug then
echo("\n没有找到可用的任务房间")
end
return nil, nil, nil
end

-- 找到最近的任务房间
local best_path = nil
local best_dirs = nil
local best_target = nil
local best_distance = math.huge

for _, target_room in ipairs(search_list) do
local path, dirs = astar_search(start_room, target_room, options)

if path and #path < best_distance then
best_path = path
best_dirs = dirs
best_target = target_room
best_distance = #path
end
end

if options.debug and best_path then
echo("\n找到最佳任务路径,目标房间: " .. best_target)
echo("\n路径长度: " .. #best_path)
end

return best_path, best_dirs, best_target
end

通用日志输出函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- 添加通用日志输出函数
-- 参数说明:
-- message: 日志消息内容
-- color: 颜色代码,默认为C.x
-- prefix: 日志前缀,默认为"<解密>"
-- how_player: 是否显示玩家ID,1为显示,0为不显示,默认为1
function log_message(message, color, prefix, how_player)
local id = var["char_id"] or "none"
local os_date = os.date("%m/%d %H:%M:%S")
color = color or C.x
prefix = prefix or "<解密>"
how_player = how_player == nil and 1 or how_player -- 如果未传入how_player,默认为1

local output = "\n" .. C.c .. prefix .. ":" .. os_date
if how_player == 1 then
output = output .. color .. "【玩家:" .. id .. "】:"
else
output = output .. color
end
output = output .. message

echo(output)
end

--[[
-- 用法示例:
-- 1. 基本用法(显示玩家ID)
log_message("这是一条日志消息", C.y, "<解密>")

-- 2. 不显示玩家ID
log_message("这是一条日志消息", C.y, "<解密>", 0)

-- 3. 显式指定显示玩家ID
log_message("这是一条日志消息", C.y, "<解密>", 1)
--]]

通用大还丹购买函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
-- 购买大还丹的通用函数
-- 参数说明:
-- target_count: 目标数量,希望携带的大还丹总数
-- callback: 购买完成后执行的回调函数,可选
function buy_da_huandan(target_count, callback)
-- 使用i命令检查物品
exec("i")
wait(0.5, function()
-- 检查当前携带的大还丹数量
local current_count = carryqty("da huandan")

-- 计算需要购买的数量
local need_count = target_count - current_count

-- 如果已经有足够的大还丹,不需要购买
if need_count <= 0 then
log_message("已有足够的大还丹,当前数量: " .. current_count, C.g)
-- 如果有回调函数,直接执行
if callback then
callback()
end
return true
end

-- 输出购买信息
log_message("当前大还丹数量: " .. current_count .. ",目标数量: " .. target_count .. ",需要购买: " .. need_count, C.y)

-- 前往扬州当铺(92)
g(92, function()
-- 执行购买逻辑
buy_huandan_recursive(need_count, target_count, callback)
end)
end)

return true
end

-- 递归购买大还丹的辅助函数
-- 由于每次只能买一个,需要递归调用
function buy_huandan_recursive(remaining, target_count, callback)
-- 如果已经购买完所需数量,结束递归
if remaining <= 0 then
-- 使用i命令检查物品
exec("i")
wait(0.5, function()
local final_count = carryqty("da huandan")
log_message("大还丹购买完成,当前数量: " .. final_count, C.g)

-- 如果有回调函数,执行它
if callback then
callback()
end
end)
return
end

-- 使用check_busy2检查是否繁忙
check_busy2(function()
-- 执行购买命令(每次只能买一个)
exec("duihuan da huandan")

-- 延迟一段时间后检查是否购买成功并继续递归
wait(1, function()
-- 使用i命令检查物品
exec("i")
wait(0.5, function()
local current_count = carryqty("da huandan")
local previous_count = target_count - remaining

-- 检查是否购买成功(当前数量比之前多)
if current_count > previous_count then
-- 购买成功,继续购买下一个
buy_huandan_recursive(target_count - current_count, target_count, callback)
else
-- 购买失败,但继续尝试购买
log_message("购买未成功,继续尝试...", C.y)
-- 继续尝试购买,不减少remaining
buy_huandan_recursive(remaining, target_count, callback)
end
end)
end)
end)
end

--[[
-- 用法示例:
-- 确保携带10个大还丹,不足则前往扬州当铺购买,完成后执行回调函数
buy_da_huandan(10, function()
log_message("购买完成后执行的操作", C.g)
-- 这里可以添加其他命令
-- exec("其他命令")
end)
--]]

通用物品购买函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
-- 通用物品购买函数
-- 参数说明:
-- item_id: 物品ID,如"da huandan"
-- target_count: 目标数量,希望携带的物品总数
-- shop_room_id: 购买物品的商店房间ID
-- buy_command: 购买物品的命令,如"duihuan da huandan"
-- callback: 购买完成后执行的回调函数,可选
-- options: 可选参数表,包含以下可选项:
-- - delay: 购买间隔延迟,默认为1秒
-- - check_delay: 检查物品延迟,默认为0.5秒
-- - prefix: 日志前缀,默认为"<解密>"
function buy_item(item_id, target_count, shop_room_id, buy_command, callback, options)
options = options or {}
local delay = options.delay or 1
local check_delay = options.check_delay or 0.5
local prefix = options.prefix or "<解密>"

-- 使用i命令检查物品
exec("i")
wait(check_delay, function()
-- 检查当前携带的物品数量
local current_count = carryqty(item_id)

-- 计算需要购买的数量
local need_count = target_count - current_count

-- 如果已经有足够的物品,不需要购买
if need_count <= 0 then
log_message("已有足够的" .. item_id .. ",当前数量: " .. current_count, C.g, prefix)
-- 如果有回调函数,直接执行
if callback then
callback()
end
return true
end

-- 输出购买信息
log_message("当前" .. item_id .. "数量: " .. current_count .. ",目标数量: " .. target_count .. ",需要购买: " .. need_count, C.y, prefix)

-- 前往指定商店
g(shop_room_id, function()
-- 执行购买逻辑
buy_item_recursive(item_id, need_count, target_count, buy_command, callback, delay, check_delay, prefix)
end)
end)

return true
end

-- 递归购买物品的辅助函数
function buy_item_recursive(item_id, remaining, target_count, buy_command, callback, delay, check_delay, prefix)
-- 如果已经购买完所需数量,结束递归
if remaining <= 0 then
-- 使用i命令检查物品
exec("i")
wait(check_delay, function()
local final_count = carryqty(item_id)
log_message(item_id .. "购买完成,当前数量: " .. final_count, C.g, prefix)

-- 如果有回调函数,执行它
if callback then
callback()
end
end)
return
end

-- 使用check_busy2检查是否繁忙
check_busy2(function()
-- 执行购买命令
exec(buy_command)

-- 延迟一段时间后检查是否购买成功并继续递归
wait(delay, function()
-- 使用i命令检查物品
exec("i")
wait(check_delay, function()
local current_count = carryqty(item_id)
local previous_count = target_count - remaining

-- 检查是否购买成功(当前数量比之前多)
if current_count > previous_count then
-- 购买成功,继续购买下一个
buy_item_recursive(item_id, target_count - current_count, target_count, buy_command, callback, delay, check_delay, prefix)
else
-- 购买失败,但继续尝试购买
log_message("购买未成功,继续尝试...", C.y, prefix)
-- 继续尝试购买,不减少remaining
buy_item_recursive(item_id, remaining, target_count, buy_command, callback, delay, check_delay, prefix)
end
end)
end)
end)
end

--[[
-- 用法示例:
-- 确保携带10个大还丹,不足则前往扬州当铺购买,完成后执行回调函数
buy_item("da huandan", 10, 92, "duihuan da huandan", function()
log_message("购买完成后执行的操作", C.g)
-- 这里可以添加其他命令
-- exec("其他命令")
end)

-- 确保携带5个金创药,不足则前往药店购买
buy_item("jin chuang yao", 5, 93, "buy jin chuang yao", nil, {prefix = "<解密>"})
--]]

通用HP检测函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
-- 通用HP检测函数
-- 参数说明:
-- trigger_name: 触发器名称,如"otherquest_tongtianta_1"
-- options: 可选参数表,包含以下可选项:
-- - qi_threshold: 气血百分比阈值,低于此值时执行恢复命令,默认为80
-- - neili_threshold: 内力阈值,低于此值时执行恢复命令,默认为5000
-- - recovery_command: 恢复命令,默认为"fu dan"
-- - callback: 自定义回调函数,可以根据HP信息执行自定义操作
function setup_hp_monitor(trigger_name, options)
options = options or {}
local qi_threshold = options.qi_threshold or 80
local neili_threshold = options.neili_threshold or 5000
local recovery_command = options.recovery_command or "fu dan"
local callback = options.callback

-- 关闭已存在的同名触发器(如果有)
close_trigger(trigger_name)

-- 添加新的HP监控触发器
add_trigger(trigger_name, "\^\\s*HP\:(.+)", function(params)
local jing, maxjing, hurtjing, jingli, maxjingli, qi, maxqi, hurtqi, neili, maxneili, jiali, shen, food, pot, maxpot, water, myexp = string.match(params[1],
"(.%d*)/(%d-)/(%d-)%%/(.%d*)/(%d-)/%d-/(.%d*)/(%d-)/(%d-)%%/(.%d*)/(%d-)/%+(%d-)/(.%d-)/%d-/%d-/(%d-)%.%d%d%%/(%d-)/(%d-)/(%d-)%.%d%d%%/(%d-)/%d")

-- 转换为数字并存入变量
var["jing"], var["maxjing"], var["hurtjing"] = tonumber(jing), tonumber(maxjing), tonumber(hurtjing)
var["jingli"], var["maxjingli"] = tonumber(jingli), tonumber(maxjingli)
var["qi"], var["maxqi"], var["hurtqi"] = tonumber(qi), tonumber(maxqi), tonumber(hurtqi)
var["neili"], var["maxneili"], var["jiali"] = tonumber(neili), tonumber(maxneili), tonumber(jiali)
var["shen"] = tonumber(shen)
var["food"], var["pot"], var["maxpot"] = tonumber(food), tonumber(pot), tonumber(maxpot)
var["water"], var["exp"] = tonumber(water), tonumber(myexp)

-- 检查是否需要恢复
if var["hurtqi"] < qi_threshold or var["neili"] < neili_threshold then
exec(recovery_command)
end

-- 如果有自定义回调函数,执行它
if callback then
callback({
jing = var["jing"], maxjing = var["maxjing"], hurtjing = var["hurtjing"],
jingli = var["jingli"], maxjingli = var["maxjingli"],
qi = var["qi"], maxqi = var["maxqi"], hurtqi = var["hurtqi"],
neili = var["neili"], maxneili = var["maxneili"], jiali = var["jiali"],
shen = var["shen"],
food = var["food"], pot = var["pot"], maxpot = var["maxpot"],
water = var["water"], exp = var["exp"]
})
end

-- 清理临时变量
jing, maxjing, hurtjing, jingli, maxjingli = nil, nil, nil, nil, nil
qi, maxqi, hurtqi, neili, maxneili = nil, nil, nil, nil, nil
jiali, shen, food, pot, maxpot = nil, nil, nil, nil, nil
water, myexp = nil, nil
end)

return trigger_name
end

-- 移除HP监控触发器
function remove_hp_monitor(trigger_name)
close_trigger(trigger_name)
end

--[[
-- 用法示例:
-- 基本用法(使用默认参数)
setup_hp_monitor("my_hp_monitor")

-- 自定义阈值和恢复命令
setup_hp_monitor("combat_hp_monitor", {
qi_threshold = 70,
neili_threshold = 3000,
recovery_command = "yun recover;yun regenerate"
})

-- 使用自定义回调函数
setup_hp_monitor("advanced_hp_monitor", {
callback = function(hp_data)
-- 根据HP数据执行自定义逻辑
if hp_data.hurtjing < 50 then
exec("yun refresh")
end

if hp_data.food < 100 then
exec("eat liang")
end

if hp_data.water < 100 then
exec("drink jiudai")
end
end
})

-- 移除监控
remove_hp_monitor("my_hp_monitor")
--]]

--简易HP检测(保留原有功能,使用新函数实现)
--setup_hp_monitor("otherquest_tongtianta_1")

通天塔层数和对应skills映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
--通天塔层数和对应skills映射
-- 根据通天塔层数返回所在范围:1(1-798), 2(799-998), 3(999-1000)
function get_ttt_level_range(level)
if not level then return 1 end

level = tonumber(level)
if level < 799 then
return 1 -- 1-798层
elseif level < 999 then
return 2 -- 799-998层
else
return 3 -- 999-1000层
end
end

-- 根据通天塔层数设置相应的技能和alias
function set_ttt_skills_by_level(level, start_level)
if not level or not var["killer_id"] then return end

level = tonumber(level)
start_level = tonumber(start_level or 0)

-- 判断是否是关键层(起始层、1层、799层或999层)
local is_key_level = (level == start_level or level == 1 or level == 799 or level == 999)

-- 获取层数范围
local range = get_ttt_level_range(level)

-- 如果是超人模式,设置相应的技能
if var["superman"] and (var["superman"] == 1 or var["superman"] == 2) then
-- 检查是否需要显示技能设置消息(只显示一次)
-- var["ttt_skills_message_shown"] 这个变量需要在每次通天塔开始时设置为 false
if not var["ttt_skills_message_shown"] then
if range == 1 then
log_message("开始层数:"..level..",超人模式,设置技能组合一", C.y, "<解密>")
var["ttt_beiskills"] = var["ttt_beiskills_1"]
var["ttt_pfm"] = var["ttt_pfm_1"]
elseif range == 2 then
log_message("开始层数:"..level..",超人模式,设置技能组合二", C.y, "<解密>")
var["ttt_beiskills"] = var["ttt_beiskills_2"]
var["ttt_pfm"] = var["ttt_pfm_2"]
elseif range == 3 then
log_message("开始层数:"..level..",超人模式,设置技能组合三", C.y, "<解密>")
var["ttt_beiskills"] = var["ttt_beiskills_3"]
var["ttt_pfm"] = var["ttt_pfm_3"]
end
-- 设置标志位为 true,表示消息已显示
var["ttt_skills_message_shown"] = true
else
-- 如果消息已经显示过,只设置技能组合,不输出日志
if range == 1 then
var["ttt_beiskills"] = var["ttt_beiskills_1"]
var["ttt_pfm"] = var["ttt_pfm_1"]
elseif range == 2 then
var["ttt_beiskills"] = var["ttt_beiskills_2"]
var["ttt_pfm"] = var["ttt_pfm_2"]
elseif range == 3 then
var["ttt_beiskills"] = var["ttt_beiskills_3"]
var["ttt_pfm"] = var["ttt_pfm_3"]
end
end

-- 在关键层设置alias
if is_key_level then
send("alias pfm " .. expand(var["ttt_pfm"]))
send("alias bei_skills " .. expand(var["ttt_beiskills"]))
send("set wimpycmd hp " .. var["char_id"] .. "\\pfm")
end
end

-- 根据不同模式和层数执行相应操作
if var["superman"] and var["superman"] == 2 then -- 超2模式
local ttt_wait_busy_1 = var["ttt_wait_busy_1"] or 2
local ttt_wait_busy_2 = var["ttt_wait_busy_2"] or 2

if is_key_level then
wait(3, function()
check_busy(function()
check_busy2(function()
exec("bei_skills")
exec("kill @pfm_id;pfm")
end)
end)
end)
elseif level < 800 then
wait(ttt_wait_busy_1, function()
exec("kill @pfm_id;pfm")
end)
else
wait(ttt_wait_busy_2, function()
exec("kill @pfm_id;pfm")
end)
end
elseif is_key_level then -- 关键层但非超2模式
wait(3, function()
check_busy(function()
check_busy2(function()
exec("bei_skills")
exec("kill @pfm_id;pfm")
end)
end)
end)
else -- 非关键层
check_busy2(function()
-- 根据层数和AOE设置决定攻击方式
if level < 799 and var["ttt_normal_aoe"] and var["ttt_normal_aoe"] == 1 then
exec("kill guard 1;kill guard 2;kill guard 3;pfm")
elseif level > 798 and level < 999 and var["ttt_super_aoe"] and var["ttt_super_aoe"] == 1 then
exec("kill guard 1;kill guard 2;kill guard 3;pfm")
elseif level > 998 and var["ttt_master_aoe"] and var["ttt_master_aoe"] == 1 then
exec("kill guard 1;kill guard 2;kill guard 3;pfm")
else
exec("kill @pfm_id;pfm")
end
end)
end
end

通用计时函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
-- 通用计时函数
-- 全局变量用于存储时间
if not var.time_tracker then
var.time_tracker = {}
end

-- 设置开始时间
-- 参数说明:
-- key: 时间标识符,用于区分不同的计时任务
function set_start_time(key)
if not key then
key = "default"
end
var.time_tracker[key] = {
start_time = os.time()
}
return var.time_tracker[key].start_time
end

-- 设置结束时间
-- 参数说明:
-- key: 时间标识符,用于区分不同的计时任务
function set_end_time(key)
if not key then
key = "default"
end
if not var.time_tracker[key] then
var.time_tracker[key] = {}
end
var.time_tracker[key].end_time = os.time()
return var.time_tracker[key].end_time
end

-- 计算时间差
-- 参数说明:
-- key: 时间标识符,用于区分不同的计时任务
-- display_mode: 显示模式
-- 0: 只显示秒
-- 1: 显示分钟和秒
-- 2: 显示小时、分钟和秒
-- 返回值:格式化后的时间字符串,如果时间未设置则返回nil

function calculate_time_diff(key, display_mode)
if not key then
key = "default"
end

-- 检查时间是否已设置
if not var.time_tracker[key] or not var.time_tracker[key].start_time then
return nil, "未设置开始时间"
end

-- 如果未设置结束时间,使用当前时间
local end_time = var.time_tracker[key].end_time or os.time()
local diff = end_time - var.time_tracker[key].start_time

-- 如果时间差小于0,返回0
if diff < 0 then
diff = 0
end

-- 准备返回结果
local result

-- 根据显示模式返回不同格式
if display_mode == 0 then
-- 模式0:只显示秒
result = align_right(diff) .. "秒"
elseif display_mode == 1 then
-- 模式1:显示分钟和秒
local minutes = math.floor(diff / 60)
local seconds = diff % 60
result = align_right(minutes) .. "分" .. align_right(seconds) .. "秒"
else
-- 模式2:显示小时、分钟和秒
local hours = math.floor(diff / 3600)
local minutes = math.floor((diff % 3600) / 60)
local seconds = diff % 60
result = align_right(hours) .. "小时" .. align_right(minutes) .. "分" .. align_right(seconds) .. "秒"
end

-- 计算完成后自动清理这个key的记录
var.time_tracker[key] = nil

return result
end


--[[
-- 用法示例:

-- 开始一个默认计时
set_start_time()

-- 开始一个指定任务的计时
set_start_time("任务1")

-- 结束默认计时
set_end_time()

-- 结束指定任务的计时
set_end_time("任务1")

-- 计算并显示时间差(秒)
local time_diff = calculate_time_diff("任务1", 0)
log_message("任务耗时:" .. time_diff, C.y)

-- 计算并显示时间差(分秒)
local time_diff = calculate_time_diff("任务1", 1)
log_message("任务耗时:" .. time_diff, C.y)

-- 计算并显示时间差(时分秒)
local time_diff = calculate_time_diff("任务1", 2)
log_message("任务耗时:" .. time_diff, C.y)
--]]

通用右对齐函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
-- 通用右对齐函数
-- 参数说明:
-- value: 要对齐的值(可以是数字或字符串)
-- width: 对齐的宽度(可选,默认为2)
-- 返回值:右对齐后的字符串
function align_right(value, width)
width = width or 2 -- 如果未指定宽度,默认为2

-- 判断输入类型并选择合适的格式化字符串
local format_type = type(value)
if format_type == "number" then
return string.format("%" .. width .. "d", value)
else
-- 将输入转换为字符串并右对齐
return string.format("%" .. width .. "s", tostring(value))
end
end

--[[
-- 用法示例:
-- 1. 数字对齐
local num1 = align_right(5) -- 返回" 5"(前面是一个空格)
local num2 = align_right(10) -- 返回"10"

-- 2. 字符串对齐
local str1 = align_right("abc", 5) -- 返回" abc"
local str2 = align_right("测试", 6) -- 返回" 测试"

-- 3. 混合使用
local name = "张三"
local score = 95
local output = align_right(name, 6) .. ":" .. align_right(score) .. "分"
-- 输出:" 张三:95分"

-- 4. 在时间显示中的应用
local hours = 5
local minutes = 30
local seconds = 8
local time = align_right(hours) .. "时" .. align_right(minutes) .. "分" .. align_right(seconds) .. "秒"
-- 输出:" 5时30分 8秒"
--]]