forked from HuiDesktop/HDTL-LuaRoot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.lua
More file actions
293 lines (253 loc) · 12.1 KB
/
Copy pathmain.lua
File metadata and controls
293 lines (253 loc) · 12.1 KB
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
require("hdtbase")
local ev = require("eventize")
local window = require("blockly_window")
local blockly_spine = require("blockly_spine38")
local dragmove = require("dragmove")
local settingsMan = require("settings")
local walkMan = require("walk")
local audio = require("blockly_audio")
local ipc = require("ipc")
local win32 = require("win32")
local args = require("args")
local modelNameFile = io.open(args.args['model'] .. "assets/name.txt", "r")
if modelNameFile == nil then log("failed to load model name") os.exit(1, true) return end
local modelName = modelNameFile:read("l")
modelNameFile:close()
ipc.addPanelItem({ type = "readonly", text = "HuiDesktop Light 明日方舟预制 " .. modelName }, function() end, function() end)
-- 工具函数
local function setPropertyValues(self, values)
for k, v in pairs(values) do
self[k](v)
end
end
local state = "idle"
local enterStateThen = {}
local enterState = function(name)
state = name
enterStateThen[name]()
end
-- 加载设置
local settings = settingsMan.load(args.args['config'] .. "/settings.json", true)
settings:default({ walk = true, drag = true, volume = 50, idleAudioProb = 60 ,startDistance = 500, stopDistance = 200, scale = 50, drop = true, transparency = 255, autoHide = true, idleMotion = 1, launchAudio = false, hittest = true })
settings:save()
local def = settingsMan.load(args.args['audio'] .. "assets/audio.conf.json", false)
ipc.addPanelItem({type="starttab"}, function() end, function() end)
ipc.addPanelItem({type="addpage", text="窗口"}, function() end, function() end)
-- 新建窗口
window.create { vsync = true, topmost = true, transparent = true, autoHide = true, settings = settings:access("window") }
win32.setTransparency(settings.transparency)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "帧率:", hint = "0为不限制(匹配屏幕刷新率)", min = 0, max = 114514 },
function(v) settings.window.fps = v window.setFPS(v) settings:save() end,
function() return settings.window.fps end)
ipc.addPanelItem(
{ type = "bool", prompt = "显示帧率", hint = "左上角数字" },
function(v) settings.window.drawFps = v settings:save() end,
function() return settings.window.drawFps end)
ipc.addPanelItem(
{ type = "bool", prompt = "全屏隐藏", hint = "有窗口全屏时是否隐藏自己" },
function(v) settings.autoHide = v window.param.autoHide = v settings:save() end,
function() return settings.autoHide end)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "透明度:", hint = "0(透明) ~ 255(不透明) 注意设置为0时窗口仍然响应点击", min = 0, max = 255 },
function(v) settings.transparency = v win32.setTransparency(v) settings:save() end,
function() return settings.transparency end)
-- 加载模型
local modelRuntimeParameters = { hittest = settings.hittest, pma = true }
local model = blockly_spine.createFromPathDefaultConfigFile(modelRuntimeParameters, args.args['model'])
setPropertyValues(model, {
scale = settings.scale / 100,
defaultMix = 0.2,
listenEvent = true })
model.setWindowSize() -- 将窗口大小设置为适合模型的状态
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "缩放(百分制):", hint = "100为一倍缩放", min = 0, max = 114514 },
function(v) settings.scale = v model.keepSetScale(v / 100) model.setWindowSize() settings:save() end,
function() return settings.scale end)
ipc.addPanelItem(
{ type = "bool", prompt = "响应点击", hint = "关闭的话小人无法点击,即可以点击到小人下方的窗口" },
function(v) modelRuntimeParameters.hittest = v settings.hittest = v settings:save() end,
function() return settings.hittest end)
-- 检查是否含有Special动画
local hasSpecial = model.findAnimation("Special") ~= nil
-- 加载音频
audio.volume(settings.volume)
audio.single = true
local idle_audios_eve = (function()
if #def.idle == 0 then return function() end end
local vs = {}
local lastPlaying = nil
for i, v in ipairs(def.idle) do vs[i] = audio.register(args.args['audio'] .. v) vs[i]:loop(false) end
return function()
if state ~= "idle" then return end
if lastPlaying ~= nil and lastPlaying:isplaying() then return end
if math.random() * settings.idleAudioProb < window.frameTime() then
lastPlaying = vs[math.random(#vs)]
lastPlaying:play()
end
end
end)()
local interact_audios = (function()
if #def.interact == 0 then return function() end end
local vs = {}
for i, v in ipairs(def.interact) do vs[i] = audio.register(args.args['audio'] .. v) vs[i]:loop(false) end
return function() vs[math.random(#vs)]:play() end
end)()
ipc.addPanelItem({type="addpage", text="语音"}, function() end, function() end)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "音量大小:", hint = "0 ~ 100", min = 0, max = 100 },
function(v) settings.volume = v audio.volume(v) settings:save() end,
function() return settings.volume end)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "随机语音安静值", hint = "默认为60(期望60秒播放一次)。如嫌闹请调大" },
function(v) settings.idleAudioProb = v settings:save() end,
function() return settings.idleAudioProb end)
-- 绑定事件
ev.on(window.draw, model.draw)
ev.on(window.after_draw, idle_audios_eve)
-- 处理idle
enterStateThen["idle"] = function()
if settings.idleMotion == 2 then model.loop("Sit")
elseif settings.idleMotion == 3 then model.loop("Sleep")
else model.loop("Relax") end
end
ipc.addPanelItem({type="addpage", text="互动"}, function() end, function() end)
ipc.addPanelItem(
{ type = "button", prompt = "切换站坐躺", hint = "变换小人的姿势(会保存下来)" },
function()
settings.idleMotion = (settings.idleMotion == 3 and 1 or settings.idleMotion + 1)
settings:save()
if state == "idle" then enterState("idle") end
end,
function() end);
-- 处理walk
(function()
local walker = walkMan.createWithWindowDefault({
checkCanStart = function() return settings.walk and state == "idle" end,
model = model, startDistance = settings.startDistance, stopDistance = settings.stopDistance, walkSpeed = 80
})
ev.on(window.after_draw, walker.trigger) -- 走动
ev.on(walker.walking, function() enterState("walk") end)
ev.on(walker.walked, function() enterState("idle") end)
ev.on(walker.directionChanged, function() model.direction(walker.direction) end)
enterStateThen["walk"] = function()
model.direction(walker.direction)
model.loop("Move")
end
ipc.addPanelItem(
{ type = "bool", prompt = "跟随鼠标", hint = "与鼠标距离太远会接近" },
function(v) settings.walk = v settings:save() end,
function() return settings.walk end)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "最远距离:", hint = "水平超过这个距离,桌宠就会走向鼠标,若不想频繁跟随就调大一些" },
function(v) v = math.max(v, settings.stopDistance) settings.startDistance = v walker.startDistance = v settings:save() end,
function() return settings.startDistance end)
ipc.addPanelItem(
{ type = "single", valueType = "number", prompt = "停止距离:", hint = "水平小于这个距离,桌宠就会停止走动,调大一点可以避免走得太近" },
function(v) settings.stopDistance = v walker.stopDistance = v settings:save() end,
function() return settings.stopDistance end)
end)();
local dragger = nil;
-- 处理drag
(function()
local updating = false
dragger = dragmove.createWithWindowDefault {
checkCanStart = function() return state == "idle" or state == "drop" end,
key = window.mouseButton.left,
model = model
}
ev.on(window.after_draw, dragger.trigger) -- 拖拽响应
ev.on(dragger.dragging, function() enterState("drag") end)
enterStateThen["drag"] = function() model.loop("Relax") end
if settings.ground == nil then
settings.ground = win32.getGround()
settings:save()
end
dragger.ground = settings.ground
enterStateThen["drop"] = function() end
ev.on(dragger.dragged, function()
dragger.drop = settings.drop and not updating
enterState((settings.drop and not updating) and "drop" or "idle")
end)
ev.on(dragger.dropped, function() enterState("idle") end)
ipc.addPanelItem(
{ type = "bool", prompt = "拖动后落地", hint = "地面默认是任务栏" },
function(v) settings.drop = v settings:save() end,
function() return settings.drop end)
local updateGroundPanelItem = { type = "button", prompt = "点击开始设定地面位置", hint = "如果想改变落地的位置,请按此按钮并根据之后提示操作" }
ipc.addPanelItem(
updateGroundPanelItem,
function()
if updating then
updating = false
settings.ground = math.floor(window.windowPos().y + model.getRawPosition().y)
dragger.ground = settings.ground
settings:save()
updateGroundPanelItem.prompt = "点击开始设定地面位置"
updateGroundPanelItem.hint = "如果想改变落地的位置,请按此按钮并根据之后提示操作"
else
updating = true
updateGroundPanelItem.prompt = "点击结束设定地面位置"
updateGroundPanelItem.hint = "将小人拖到你觉得合适的地面位置,然后点击结束即可"
end
end,
function() end)
if settings.drop then
window.setPosition(window.windowPos().x, settings.ground - model.getRawPosition().y)
end
end)();
log(hasSpecial);
-- 处理互动
(function()
local special = false
enterStateThen["interact"] = (function()
if hasSpecial then return function () model.once(math.random(5) == 1 and "Special" or "Interact") interact_audios() special = false end
else return function () model.once("Interact") interact_audios() special = false end end
end)()
if dragger then ev.on(dragger.clicked, function () enterState("interact") end) end -- fuck!
ev.on(model.spine_complete, function() if state == "interact" then enterState("idle") end end)
if hasSpecial then
ev.on(window.before_draw, function()
if state == "idle" and math.random() * 180 < window.frameTime() then
special = true
model.once("Special")
end
end)
ev.on(model.spine_complete, function() if state == "idle" and special then enterState("idle") end end)
end
end)();
ipc.addPanelItem({type="addpage", text="重置"}, function() end, function() end)
ipc.addPanelItem(
{ type = "button", prompt = "重置小人坐标", hint = "如屏幕里面找不到小人,请最小化所有窗口然后点击此按钮" },
function()
window.setPosition(0, 0)
settings:save()
enterState("idle")
end,
function() end)
ipc.addPanelItem({type="addpage", text="启动"}, function() end, function() end)
-- 启动语音
if #def.launch == 0 then
ipc.addPanelItem({ type = "readonly", text = "本配置没有语音……" }, function() end, function() end)
else
if settings.launchAudio and #def.launch > 0 then
local au = audio.register(args.args['audio'] .. def.launch[math.random(#def.launch)])
au:loop(false)
au:play()
end
ipc.addPanelItem(
{ type = "bool", prompt = "启动时播放问候语音", hint = "默认关闭,以防社死" },
function(v) settings.launchAudio = v settings:save() end,
function() return settings.launchAudio end)
end
ipc.addPanelItem({type="endtab"}, function() end, function() end)
-- ipc
if args.ipc ~= nil then
-- open ipc
local rxIpcInst = ipc.lib.hiMQ_openIPC(args.ipc[1])
local txIpcInst = ipc.lib.hiMQ_openIPC(args.ipc[2])
ev.on(window.after_draw, function() ipc.read(rxIpcInst, txIpcInst) end)
ipc.sendPanelStructure(txIpcInst)
end
enterState("idle")
window.run()