koishi-plugin-smmcat-gensokyo 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +1920 -1596
- package/lib/map.d.ts +1 -1
- package/lib/mapHtml.d.ts +6 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -28,429 +28,6 @@ __export(src_exports, {
|
|
|
28
28
|
module.exports = __toCommonJS(src_exports);
|
|
29
29
|
var import_koishi2 = require("koishi");
|
|
30
30
|
|
|
31
|
-
// src/map.ts
|
|
32
|
-
var delay = /* @__PURE__ */ __name((ms) => new Promise((resolve) => setTimeout(resolve, ms)), "delay");
|
|
33
|
-
var GensokyoMap = {
|
|
34
|
-
config: {},
|
|
35
|
-
ctx: {},
|
|
36
|
-
mapLocalData: {},
|
|
37
|
-
userCurrentLoal: {},
|
|
38
|
-
async init(config, ctx) {
|
|
39
|
-
GensokyoMap.config = config;
|
|
40
|
-
GensokyoMap.ctx = ctx;
|
|
41
|
-
ctx.database.extend("smm_gensokyo_map_position", {
|
|
42
|
-
userId: "string",
|
|
43
|
-
floor: "integer",
|
|
44
|
-
areaName: "string",
|
|
45
|
-
moveing: "boolean",
|
|
46
|
-
playName: "string"
|
|
47
|
-
}, {
|
|
48
|
-
primary: "userId",
|
|
49
|
-
autoInc: false
|
|
50
|
-
});
|
|
51
|
-
GensokyoMap.mapLocalData = {
|
|
52
|
-
1: {
|
|
53
|
-
"地下墓穴": {
|
|
54
|
-
floor: 1,
|
|
55
|
-
areaName: "地下墓穴",
|
|
56
|
-
type: "BOSS区" /* BOSS区 */,
|
|
57
|
-
needLv: 1,
|
|
58
|
-
down: "蜘蛛洞穴",
|
|
59
|
-
monster: [{ name: "古明地觉", lv: 15 }]
|
|
60
|
-
},
|
|
61
|
-
"蜘蛛洞穴": {
|
|
62
|
-
floor: 1,
|
|
63
|
-
areaName: "蜘蛛洞穴",
|
|
64
|
-
type: "冒险区" /* 冒险区 */,
|
|
65
|
-
needLv: 1,
|
|
66
|
-
top: "地下墓穴",
|
|
67
|
-
down: "蜘蛛森林一"
|
|
68
|
-
},
|
|
69
|
-
"蜘蛛森林一": {
|
|
70
|
-
floor: 1,
|
|
71
|
-
areaName: "蜘蛛森林一",
|
|
72
|
-
type: "冒险区" /* 冒险区 */,
|
|
73
|
-
needLv: 1,
|
|
74
|
-
monster: [{ name: "小蜘蛛", lv: 2 }],
|
|
75
|
-
top: "蜘蛛洞穴",
|
|
76
|
-
left: "蜘蛛森林二",
|
|
77
|
-
right: "蜘蛛森林三",
|
|
78
|
-
down: "蜘蛛森林通道"
|
|
79
|
-
},
|
|
80
|
-
"蜘蛛森林二": {
|
|
81
|
-
floor: 1,
|
|
82
|
-
areaName: "蜘蛛森林二",
|
|
83
|
-
type: "冒险区" /* 冒险区 */,
|
|
84
|
-
needLv: 1,
|
|
85
|
-
right: "蜘蛛森林一"
|
|
86
|
-
},
|
|
87
|
-
"蜘蛛森林三": {
|
|
88
|
-
floor: 1,
|
|
89
|
-
areaName: "蜘蛛森林三",
|
|
90
|
-
type: "冒险区" /* 冒险区 */,
|
|
91
|
-
needLv: 1,
|
|
92
|
-
left: "蜘蛛森林一",
|
|
93
|
-
monster: [{ name: "大妖精", lv: 3 }]
|
|
94
|
-
},
|
|
95
|
-
"蜘蛛森林通道": {
|
|
96
|
-
floor: 1,
|
|
97
|
-
areaName: "蜘蛛森林通道",
|
|
98
|
-
type: "冒险区" /* 冒险区 */,
|
|
99
|
-
needLv: 1,
|
|
100
|
-
top: "蜘蛛森林一",
|
|
101
|
-
down: "中央广场"
|
|
102
|
-
},
|
|
103
|
-
"中央广场": {
|
|
104
|
-
floor: 1,
|
|
105
|
-
areaName: "中央广场",
|
|
106
|
-
info: "一层的中心位置,梦开始的地方",
|
|
107
|
-
npc: ["aipo"],
|
|
108
|
-
type: "安全区" /* 安全区 */,
|
|
109
|
-
needLv: 1,
|
|
110
|
-
top: "蜘蛛森林通道",
|
|
111
|
-
down: "新手村",
|
|
112
|
-
left: "酒馆",
|
|
113
|
-
right: "银行"
|
|
114
|
-
},
|
|
115
|
-
"酒馆": {
|
|
116
|
-
floor: 1,
|
|
117
|
-
areaName: "酒馆",
|
|
118
|
-
type: "安全区" /* 安全区 */,
|
|
119
|
-
needLv: 1,
|
|
120
|
-
down: "传送门",
|
|
121
|
-
right: "中央广场"
|
|
122
|
-
},
|
|
123
|
-
"银行": {
|
|
124
|
-
floor: 1,
|
|
125
|
-
areaName: "银行",
|
|
126
|
-
type: "安全区" /* 安全区 */,
|
|
127
|
-
needLv: 1,
|
|
128
|
-
down: "1层-商店",
|
|
129
|
-
left: "中央广场"
|
|
130
|
-
},
|
|
131
|
-
"1层-商店": {
|
|
132
|
-
floor: 1,
|
|
133
|
-
areaName: "1层-商店",
|
|
134
|
-
type: "安全区" /* 安全区 */,
|
|
135
|
-
needLv: 1,
|
|
136
|
-
right: "农田",
|
|
137
|
-
left: "新手村"
|
|
138
|
-
},
|
|
139
|
-
"传送门": {
|
|
140
|
-
floor: 1,
|
|
141
|
-
areaName: "传送门",
|
|
142
|
-
type: "传送门" /* 传送门 */,
|
|
143
|
-
needLv: 1,
|
|
144
|
-
top: "酒馆",
|
|
145
|
-
right: "新手村",
|
|
146
|
-
left: "爱之湖"
|
|
147
|
-
},
|
|
148
|
-
"爱之湖": {
|
|
149
|
-
floor: 1,
|
|
150
|
-
areaName: "传送门",
|
|
151
|
-
type: "安全区" /* 安全区 */,
|
|
152
|
-
needLv: 1,
|
|
153
|
-
right: "传送门"
|
|
154
|
-
},
|
|
155
|
-
"新手村": {
|
|
156
|
-
floor: 1,
|
|
157
|
-
areaName: "新手村",
|
|
158
|
-
type: "安全区" /* 安全区 */,
|
|
159
|
-
needLv: 1,
|
|
160
|
-
top: "中央广场",
|
|
161
|
-
down: "绿野平原通道",
|
|
162
|
-
left: "传送门",
|
|
163
|
-
right: "1层-商店"
|
|
164
|
-
},
|
|
165
|
-
"绿野平原通道": {
|
|
166
|
-
floor: 1,
|
|
167
|
-
areaName: "绿野平原通道",
|
|
168
|
-
type: "安全区" /* 安全区 */,
|
|
169
|
-
needLv: 1,
|
|
170
|
-
top: "新手村",
|
|
171
|
-
down: "绿野平原一"
|
|
172
|
-
},
|
|
173
|
-
"绿野平原一": {
|
|
174
|
-
floor: 1,
|
|
175
|
-
areaName: "绿野平原一",
|
|
176
|
-
type: "冒险区" /* 冒险区 */,
|
|
177
|
-
monster: [{ name: "小蜜蜂", lv: 1 }, { name: "dora", lv: 2 }],
|
|
178
|
-
needLv: 1,
|
|
179
|
-
top: "绿野平原通道",
|
|
180
|
-
left: "绿野平原二",
|
|
181
|
-
right: "绿野平原三",
|
|
182
|
-
down: "绿野平原四"
|
|
183
|
-
},
|
|
184
|
-
"绿野平原二": {
|
|
185
|
-
floor: 1,
|
|
186
|
-
areaName: "绿野平原二",
|
|
187
|
-
type: "冒险区" /* 冒险区 */,
|
|
188
|
-
monster: [{ name: "dora", lv: 2 }, { name: "dora", lv: 2 }, { name: "dora", lv: 3 }, { name: "dora", lv: 2 }],
|
|
189
|
-
needLv: 1,
|
|
190
|
-
right: "绿野平原一",
|
|
191
|
-
down: "绿野平原五"
|
|
192
|
-
},
|
|
193
|
-
"绿野平原三": {
|
|
194
|
-
floor: 1,
|
|
195
|
-
areaName: "绿野平原三",
|
|
196
|
-
type: "冒险区" /* 冒险区 */,
|
|
197
|
-
monster: [{ name: "dora", lv: 5 }],
|
|
198
|
-
needLv: 1,
|
|
199
|
-
left: "绿野平原一",
|
|
200
|
-
down: "绿野平原六"
|
|
201
|
-
},
|
|
202
|
-
"绿野平原四": {
|
|
203
|
-
floor: 1,
|
|
204
|
-
areaName: "绿野平原四",
|
|
205
|
-
type: "冒险区" /* 冒险区 */,
|
|
206
|
-
needLv: 1,
|
|
207
|
-
top: "绿野平原一",
|
|
208
|
-
down: "野猪巢穴",
|
|
209
|
-
left: "绿野平原五",
|
|
210
|
-
right: "绿野平原六",
|
|
211
|
-
monster: [{ name: "琪露诺", lv: 10 }]
|
|
212
|
-
},
|
|
213
|
-
"绿野平原五": {
|
|
214
|
-
floor: 1,
|
|
215
|
-
areaName: "绿野平原五",
|
|
216
|
-
type: "冒险区" /* 冒险区 */,
|
|
217
|
-
needLv: 1,
|
|
218
|
-
top: "绿野平原二",
|
|
219
|
-
right: "绿野平原四"
|
|
220
|
-
},
|
|
221
|
-
"绿野平原六": {
|
|
222
|
-
floor: 1,
|
|
223
|
-
areaName: "绿野平原六",
|
|
224
|
-
type: "冒险区" /* 冒险区 */,
|
|
225
|
-
needLv: 1,
|
|
226
|
-
left: "绿野平原四",
|
|
227
|
-
top: "绿野平原三",
|
|
228
|
-
monster: [{ name: "绿毒蛇", lv: 12 }]
|
|
229
|
-
},
|
|
230
|
-
"野猪巢穴": {
|
|
231
|
-
floor: 1,
|
|
232
|
-
areaName: "野猪巢穴",
|
|
233
|
-
type: "BOSS区" /* BOSS区 */,
|
|
234
|
-
needLv: 1,
|
|
235
|
-
top: "绿野平原四",
|
|
236
|
-
monster: [{ name: "蓬莱山辉夜", lv: 20 }]
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
2: {
|
|
240
|
-
"传送门": {
|
|
241
|
-
floor: 2,
|
|
242
|
-
areaName: "传送门",
|
|
243
|
-
type: "传送门" /* 传送门 */,
|
|
244
|
-
needLv: 1,
|
|
245
|
-
right: "希望之泉"
|
|
246
|
-
},
|
|
247
|
-
"希望之泉": {
|
|
248
|
-
floor: 2,
|
|
249
|
-
areaName: "希望之泉",
|
|
250
|
-
type: "安全区" /* 安全区 */,
|
|
251
|
-
needLv: 1,
|
|
252
|
-
top: "爱之湖",
|
|
253
|
-
down: "农田",
|
|
254
|
-
left: "传送门",
|
|
255
|
-
right: "2层-商店"
|
|
256
|
-
},
|
|
257
|
-
"爱之湖": {
|
|
258
|
-
floor: 2,
|
|
259
|
-
areaName: "爱之湖",
|
|
260
|
-
type: "安全区" /* 安全区 */,
|
|
261
|
-
needLv: 1,
|
|
262
|
-
down: "希望之泉",
|
|
263
|
-
right: "旅馆"
|
|
264
|
-
},
|
|
265
|
-
"农田": {
|
|
266
|
-
floor: 2,
|
|
267
|
-
areaName: "农田",
|
|
268
|
-
type: "安全区" /* 安全区 */,
|
|
269
|
-
needLv: 1,
|
|
270
|
-
top: "希望之泉",
|
|
271
|
-
right: "银行"
|
|
272
|
-
},
|
|
273
|
-
"银行": {
|
|
274
|
-
floor: 2,
|
|
275
|
-
areaName: "银行",
|
|
276
|
-
type: "安全区" /* 安全区 */,
|
|
277
|
-
needLv: 1,
|
|
278
|
-
top: "2层-商店",
|
|
279
|
-
left: "农田"
|
|
280
|
-
},
|
|
281
|
-
"旅馆": {
|
|
282
|
-
floor: 2,
|
|
283
|
-
areaName: "旅馆",
|
|
284
|
-
type: "安全区" /* 安全区 */,
|
|
285
|
-
needLv: 1,
|
|
286
|
-
down: "2层-商店",
|
|
287
|
-
left: "爱之湖"
|
|
288
|
-
},
|
|
289
|
-
"2层-商店": {
|
|
290
|
-
floor: 2,
|
|
291
|
-
areaName: "2层-商店",
|
|
292
|
-
type: "安全区" /* 安全区 */,
|
|
293
|
-
needLv: 1,
|
|
294
|
-
right: "大草场"
|
|
295
|
-
},
|
|
296
|
-
"大草场": {
|
|
297
|
-
floor: 2,
|
|
298
|
-
areaName: "大草场",
|
|
299
|
-
type: "安全区" /* 安全区 */,
|
|
300
|
-
needLv: 1,
|
|
301
|
-
left: "2层-商店",
|
|
302
|
-
right: "森林岔口"
|
|
303
|
-
},
|
|
304
|
-
"森林岔口": {
|
|
305
|
-
floor: 2,
|
|
306
|
-
areaName: "森林岔口",
|
|
307
|
-
type: "安全区" /* 安全区 */,
|
|
308
|
-
needLv: 1,
|
|
309
|
-
left: "大草场"
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
console.log(JSON.stringify(GensokyoMap.mapLocalData));
|
|
314
|
-
const userPoistionList = await ctx.database.get("smm_gensokyo_map_position", {});
|
|
315
|
-
const poistionTemp = {};
|
|
316
|
-
userPoistionList.forEach((poistion) => {
|
|
317
|
-
poistion.moveing = false;
|
|
318
|
-
poistionTemp[poistion.userId] = poistion;
|
|
319
|
-
});
|
|
320
|
-
GensokyoMap.userCurrentLoal = poistionTemp;
|
|
321
|
-
},
|
|
322
|
-
/** 获取层的数据 */
|
|
323
|
-
getBaseFloorLocal(floor) {
|
|
324
|
-
return GensokyoMap.mapLocalData[floor] || null;
|
|
325
|
-
},
|
|
326
|
-
/** 获取用户当前区域信息 */
|
|
327
|
-
getUserCurrentArea(userid) {
|
|
328
|
-
const { floor, areaName } = GensokyoMap.userCurrentLoal[userid] || {};
|
|
329
|
-
if (!(floor && areaName)) return null;
|
|
330
|
-
return GensokyoMap.mapLocalData[floor][areaName] || null;
|
|
331
|
-
},
|
|
332
|
-
/** 初始化用户位置 */
|
|
333
|
-
initUserPoistion(session, userData) {
|
|
334
|
-
if (!GensokyoMap.userCurrentLoal[session.userId]) {
|
|
335
|
-
GensokyoMap.userCurrentLoal[session.userId] = {
|
|
336
|
-
userId: session.userId,
|
|
337
|
-
floor: 1,
|
|
338
|
-
areaName: "传送门",
|
|
339
|
-
moveing: false,
|
|
340
|
-
playName: userData.playName
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
344
|
-
},
|
|
345
|
-
/** 位置信息存储到数据库 */
|
|
346
|
-
async setLocalStoragePoistionData(userId) {
|
|
347
|
-
const poistionData = { ...GensokyoMap.userCurrentLoal[userId] };
|
|
348
|
-
if (poistionData) {
|
|
349
|
-
const [localData] = await GensokyoMap.ctx.database.get("smm_gensokyo_map_position", { userId });
|
|
350
|
-
if (!localData) {
|
|
351
|
-
await GensokyoMap.ctx.database.create("smm_gensokyo_map_position", poistionData);
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
delete poistionData.userId;
|
|
355
|
-
await GensokyoMap.ctx.database.set("smm_gensokyo_map_position", { userId }, poistionData);
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
/** 用户移动 */
|
|
359
|
-
async move(session, type, fn) {
|
|
360
|
-
try {
|
|
361
|
-
const userCurrentArea = GensokyoMap.userCurrentLoal[session.userId] || {};
|
|
362
|
-
const { floor, areaName, moveing } = userCurrentArea;
|
|
363
|
-
if (moveing) {
|
|
364
|
-
await session.send("当前移动冷却中,请稍等...");
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
if (!(floor && areaName)) {
|
|
368
|
-
await session.send("您当前位置有误,请使用(还没写好的指令)脱离卡死...");
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
userCurrentArea.moveing = true;
|
|
372
|
-
const nowPosition = GensokyoMap.mapLocalData[floor][areaName];
|
|
373
|
-
if (!nowPosition[type]) {
|
|
374
|
-
await session.send("抱歉,此路不通!");
|
|
375
|
-
userCurrentArea.moveing = false;
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
const newArea = GensokyoMap.mapLocalData[floor][nowPosition[type]];
|
|
379
|
-
if (!newArea) {
|
|
380
|
-
await session.send("进入失败,地图中不存在 " + nowPosition[type] + " 这个区域。");
|
|
381
|
-
userCurrentArea.moveing = false;
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
if (newArea.type == "禁用" /* 禁用 */) {
|
|
385
|
-
await session.send(`该区域暂时未开放...`);
|
|
386
|
-
userCurrentArea.moveing = false;
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
if (newArea.needLv > 1) {
|
|
390
|
-
await session.send(`当前区域由于您的等级未达到最低要求,暂时无法进入。
|
|
391
|
-
需要等级:${newArea.needLv}级`);
|
|
392
|
-
userCurrentArea.moveing = false;
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
userCurrentArea.areaName = newArea.areaName;
|
|
396
|
-
const areaInfo = {
|
|
397
|
-
user: { ...userCurrentArea },
|
|
398
|
-
map: { ...newArea }
|
|
399
|
-
};
|
|
400
|
-
fn && await fn(areaInfo);
|
|
401
|
-
await delay(3e3);
|
|
402
|
-
userCurrentArea.moveing = false;
|
|
403
|
-
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
404
|
-
return;
|
|
405
|
-
} catch (error) {
|
|
406
|
-
console.log(error);
|
|
407
|
-
if (GensokyoMap.userCurrentLoal?.[session.userId]) {
|
|
408
|
-
GensokyoMap.userCurrentLoal[session.userId].moveing = false;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
/** 查询附近玩家 */
|
|
413
|
-
nearbyPlayersByUserId(userId) {
|
|
414
|
-
const areaData = GensokyoMap.getUserCurrentArea(userId);
|
|
415
|
-
const liveUser = [];
|
|
416
|
-
Object.keys(GensokyoMap.userCurrentLoal).forEach((_userId) => {
|
|
417
|
-
const userItem = GensokyoMap.userCurrentLoal[_userId];
|
|
418
|
-
if (userItem.areaName == areaData.areaName && userItem.floor == areaData.floor) {
|
|
419
|
-
if (userId !== userItem.userId) {
|
|
420
|
-
liveUser.push({ userId: userItem.userId, playName: userItem.playName });
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
return liveUser;
|
|
425
|
-
},
|
|
426
|
-
/** 区域信息格式化 */
|
|
427
|
-
userAreaTextFormat(gameName, data) {
|
|
428
|
-
const liveUser = [];
|
|
429
|
-
Object.keys(GensokyoMap.userCurrentLoal).forEach((userId) => {
|
|
430
|
-
const areaItem = GensokyoMap.userCurrentLoal[userId];
|
|
431
|
-
if (areaItem.areaName == data.map.areaName && areaItem.floor == data.map.floor) {
|
|
432
|
-
if (gameName !== areaItem.playName) {
|
|
433
|
-
liveUser.push(areaItem.playName);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
const str = `${gameName}[萌新] 当前位置:
|
|
438
|
-
`;
|
|
439
|
-
const mapInfo = `区域:【${data.map.areaName}】
|
|
440
|
-
` + (data.map.info ? data.map.info + "\n\n" : "\n") + (data.map.top ? `上:【${data.map.top}】
|
|
441
|
-
` : "") + (data.map.down ? `下:【${data.map.down}】
|
|
442
|
-
` : "") + (data.map.left ? `左:【${data.map.left}】
|
|
443
|
-
` : "") + (data.map.right ? `右:【${data.map.right}】
|
|
444
|
-
` : "") + (data.map.type == "传送门" /* 传送门 */ ? `
|
|
445
|
-
[!]传送门区域` : "") + (data.map.shopName ? `
|
|
446
|
-
[!]存在商店:${data.map.shopName}` : "") + (data.map.npc ? `
|
|
447
|
-
[!]存在npc:${data.map.npc.join("、")}` : "") + (data.map.monster ? `
|
|
448
|
-
[!]存在野怪:${data.map.monster.map((i) => `lv.${i.lv} ${i.name}`).join("、")}` : "") + (liveUser.length ? `
|
|
449
|
-
[!]区域玩家:${liveUser.length > 3 ? liveUser.slice(0, 3).join("、") + `...等${liveUser.length}` : liveUser.join("、")}` : "");
|
|
450
|
-
return str + mapInfo;
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
|
|
454
31
|
// src/data/benchmark.ts
|
|
455
32
|
var monsterBenchmark = {
|
|
456
33
|
10: {
|
|
@@ -1460,1229 +1037,1988 @@ var BattleData = {
|
|
|
1460
1037
|
isTeamByUserId(userId) {
|
|
1461
1038
|
return !!BattleData.teamTemp[userId];
|
|
1462
1039
|
},
|
|
1463
|
-
// 返回队伍信息
|
|
1464
|
-
teamListByUser(userId) {
|
|
1465
|
-
const teamList = [];
|
|
1466
|
-
if (!BattleData.teamTemp[userId]) {
|
|
1467
|
-
return [];
|
|
1040
|
+
// 返回队伍信息
|
|
1041
|
+
teamListByUser(userId) {
|
|
1042
|
+
const teamList = [];
|
|
1043
|
+
if (!BattleData.teamTemp[userId]) {
|
|
1044
|
+
return [];
|
|
1045
|
+
}
|
|
1046
|
+
const _userId = BattleData.teamTemp[userId].for;
|
|
1047
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1048
|
+
if (BattleData.teamTemp[item].for == _userId) {
|
|
1049
|
+
teamList.push(User.getUserAttributeByUserId(item));
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
return teamList;
|
|
1053
|
+
},
|
|
1054
|
+
/** 创建队伍 */
|
|
1055
|
+
async creatTeam(session) {
|
|
1056
|
+
const { userId } = session;
|
|
1057
|
+
if (BattleData.isTeamByUserId(userId)) {
|
|
1058
|
+
await session.send(`${User.getUserName(userId)}:你已经加入了${BattleData.teamTemp[userId].for}的队伍,需要退出才可以重新创建!`);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
BattleData.teamTemp[userId] = {
|
|
1062
|
+
for: userId,
|
|
1063
|
+
identity: "队长"
|
|
1064
|
+
};
|
|
1065
|
+
await session.send("创建队伍成功!发送 /队伍邀请 昵称 \n可对周围对应昵称玩家进行组队邀请!");
|
|
1066
|
+
},
|
|
1067
|
+
/** 邀请加入队伍 */
|
|
1068
|
+
async invitationTeam(session, playName) {
|
|
1069
|
+
const { userId } = session;
|
|
1070
|
+
if (!BattleData.isTeamByUserId(userId)) {
|
|
1071
|
+
await session.send(`你还没有创建队伍,请发送 /队伍创建 创建队伍吧!`);
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
const teamInfo = BattleData.teamTemp[userId];
|
|
1075
|
+
if (teamInfo.identity !== "队长") {
|
|
1076
|
+
await session.send(`你不是小队队长,无法邀请玩家加入!`);
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
const nearUser = GensokyoMap.nearbyPlayersByUserId(userId);
|
|
1080
|
+
const invitationUser = nearUser.find((item) => item.playName == playName);
|
|
1081
|
+
if (!invitationUser) {
|
|
1082
|
+
await session.send(`玩家${playName}不在你附近,邀请失败!`);
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
if (BattleData.isTeamByUserId(invitationUser.userId)) {
|
|
1086
|
+
await session.send(`对方已经组队,或者已经在队伍中!`);
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
BattleData.invitationTemp[invitationUser.userId] = {
|
|
1090
|
+
time: Date.now(),
|
|
1091
|
+
for: userId,
|
|
1092
|
+
playName: User.getUserName(userId),
|
|
1093
|
+
seen: false
|
|
1094
|
+
};
|
|
1095
|
+
await session.send(`已经发送邀请,等待TA的 /队伍加入 操作`);
|
|
1096
|
+
},
|
|
1097
|
+
/** 加入队伍 */
|
|
1098
|
+
async joinTeam(session) {
|
|
1099
|
+
const { userId } = session;
|
|
1100
|
+
if (!BattleData.invitationTemp[userId]) {
|
|
1101
|
+
await session.send("当前最后记录中无人邀请你加入队伍...");
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
if (BattleData.isTeamByUserId(userId)) {
|
|
1105
|
+
await session.send(`你已经在队伍中,无法再次加入,若需要加入请发送 /队伍退出`);
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const invInfo = BattleData.invitationTemp[userId];
|
|
1109
|
+
if (Date.now() - invInfo.time > 36e5) {
|
|
1110
|
+
await session.send(`${invInfo.playName}的邀请队伍请求已超时!`);
|
|
1111
|
+
delete BattleData.invitationTemp[userId];
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (BattleData.teamListByUser(invInfo.for).length >= 4) {
|
|
1115
|
+
await session.send(`${invInfo.playName}的队伍人员已满!无法加入`);
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
BattleData.teamTemp[userId] = {
|
|
1119
|
+
for: invInfo.for,
|
|
1120
|
+
identity: "队员"
|
|
1121
|
+
};
|
|
1122
|
+
await session.send(`加入${invInfo.playName}的队伍成功!
|
|
1123
|
+
若后续需要退出可发送 /队伍退出`);
|
|
1124
|
+
},
|
|
1125
|
+
/** 退出队伍 */
|
|
1126
|
+
async exitTeam(session) {
|
|
1127
|
+
const { userId } = session;
|
|
1128
|
+
if (!BattleData.isTeamByUserId(userId)) {
|
|
1129
|
+
await session.send("你还没有加入任何队伍!");
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (BattleData.teamTemp[userId].identity == "队长") {
|
|
1133
|
+
await session.send("你是小队队长,无法退出。若要解散队伍,请发送 /队伍解散");
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
const teamName = User.getUserName(BattleData.teamTemp[userId].for);
|
|
1137
|
+
delete BattleData.teamTemp[userId];
|
|
1138
|
+
await session.send(`退出${teamName}的小队成功!`);
|
|
1139
|
+
},
|
|
1140
|
+
/** 解散队伍 */
|
|
1141
|
+
async dissolveTeam(session) {
|
|
1142
|
+
const { userId } = session;
|
|
1143
|
+
if (!BattleData.isTeamByUserId(userId)) {
|
|
1144
|
+
await session.send("你还没有加入任何队伍!");
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
if (BattleData.teamTemp[userId].identity == "队员") {
|
|
1148
|
+
await session.send("你不是小队队长,无法解散。");
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
const team = BattleData.teamListByUser(userId);
|
|
1152
|
+
team.forEach((item) => {
|
|
1153
|
+
delete BattleData.teamTemp[item.userId];
|
|
1154
|
+
});
|
|
1155
|
+
await session.send("操作成功,已经解散你创建的小队。");
|
|
1156
|
+
},
|
|
1157
|
+
/** 创建战斗-与怪物 */
|
|
1158
|
+
async createBattleByMonster(session, goal) {
|
|
1159
|
+
if (BattleData.isBattle(session)) {
|
|
1160
|
+
await session.send("当前正在战斗,还不能逃脱!");
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
const battle_user = [];
|
|
1164
|
+
const battle_monsterList = [];
|
|
1165
|
+
const playUser = [];
|
|
1166
|
+
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1167
|
+
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1168
|
+
return;
|
|
1169
|
+
} else if (BattleData.isTeam(session)) {
|
|
1170
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1171
|
+
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1172
|
+
playUser.push(item);
|
|
1173
|
+
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
} else {
|
|
1177
|
+
playUser.push(session.userId);
|
|
1178
|
+
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
1179
|
+
}
|
|
1180
|
+
goal.forEach((item) => {
|
|
1181
|
+
battle_monsterList.push(initBattleAttribute(Monster.getMonsterAttributeData(item.name, item.lv)));
|
|
1182
|
+
});
|
|
1183
|
+
const temp = {
|
|
1184
|
+
self: battle_user.map((i) => ({ ...i, for: "self" })),
|
|
1185
|
+
goal: battle_monsterList.map((i) => ({ ...i, for: "goal" }))
|
|
1186
|
+
};
|
|
1187
|
+
playUser.forEach((userId) => {
|
|
1188
|
+
BattleData.lastPlay[userId] = temp;
|
|
1189
|
+
});
|
|
1190
|
+
await session.send(`开始与 ${goal.map((i) => i.name).join("、")} 进行战斗`);
|
|
1191
|
+
},
|
|
1192
|
+
/** 创建战斗-与玩家 */
|
|
1193
|
+
async createBattleByUser(session, goal) {
|
|
1194
|
+
if (BattleData.isBattle(session)) {
|
|
1195
|
+
await session.send("当前正在战斗,还不能逃脱!");
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const battle_self = [];
|
|
1199
|
+
const battle_goal = [];
|
|
1200
|
+
const playUser = [];
|
|
1201
|
+
const lostMsg = [];
|
|
1202
|
+
goal = goal.filter((item) => {
|
|
1203
|
+
const isBattle = BattleData.isBattleByUserId(item.userId);
|
|
1204
|
+
const pyUser = User.userTempData[item.userId];
|
|
1205
|
+
if (isBattle) {
|
|
1206
|
+
lostMsg.push(`${pyUser.playName}正在参与着一场战斗,无法被PK选中。`);
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
return true;
|
|
1210
|
+
});
|
|
1211
|
+
if (lostMsg.length) {
|
|
1212
|
+
await session.send(lostMsg.join("\n"));
|
|
1213
|
+
}
|
|
1214
|
+
if (!goal.length) {
|
|
1215
|
+
lostMsg.push(`PK失败,无任何目标进行PK`);
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1219
|
+
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1220
|
+
return;
|
|
1221
|
+
} else if (BattleData.isTeam(session)) {
|
|
1222
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1223
|
+
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1224
|
+
playUser.push(item);
|
|
1225
|
+
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
} else {
|
|
1229
|
+
playUser.push(session.userId);
|
|
1230
|
+
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
1231
|
+
}
|
|
1232
|
+
goal.forEach((item) => {
|
|
1233
|
+
playUser.push(item.userId);
|
|
1234
|
+
battle_goal.push(initBattleAttribute(User.getUserAttributeByUserId(item.userId)));
|
|
1235
|
+
});
|
|
1236
|
+
const pkTemp = {
|
|
1237
|
+
self: battle_self.map((i) => ({ ...i, for: "self" })),
|
|
1238
|
+
goal: battle_goal.map((i) => ({ ...i, for: "goal" })),
|
|
1239
|
+
isPK: true
|
|
1240
|
+
};
|
|
1241
|
+
playUser.forEach((userId) => {
|
|
1242
|
+
BattleData.lastPlay[userId] = pkTemp;
|
|
1243
|
+
});
|
|
1244
|
+
await session.send(`开始与玩家 ${battle_goal.map((i) => i.name).join("、")} 进行PK战斗`);
|
|
1245
|
+
},
|
|
1246
|
+
/** 文本化当前战况 */
|
|
1247
|
+
battleSituationTextFormat(team) {
|
|
1248
|
+
const selfTemp = [];
|
|
1249
|
+
const goalTemp = [];
|
|
1250
|
+
const getBuffTemplate = /* @__PURE__ */ __name((agent) => {
|
|
1251
|
+
const dict = { 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" };
|
|
1252
|
+
const buffInfo = Object.keys(agent.buff).map((item) => {
|
|
1253
|
+
return `${agent.buff[item].name}${dict[agent.buff[item].timer] || "⁺"}`;
|
|
1254
|
+
});
|
|
1255
|
+
return buffInfo.length ? "(" + buffInfo.join(" ") + ")" : "";
|
|
1256
|
+
}, "getBuffTemplate");
|
|
1257
|
+
team.self.forEach((item) => {
|
|
1258
|
+
if (item.hp > 0) {
|
|
1259
|
+
selfTemp.push(`lv.${item.lv}[${item.name}]${getBuffTemplate(item)}:
|
|
1260
|
+
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1261
|
+
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1262
|
+
} else {
|
|
1263
|
+
selfTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1264
|
+
}
|
|
1265
|
+
});
|
|
1266
|
+
team.goal.forEach((item) => {
|
|
1267
|
+
if (item.hp > 0) {
|
|
1268
|
+
goalTemp.push(`lv.${item.lv}[${item.name}]${getBuffTemplate(item)}:
|
|
1269
|
+
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1270
|
+
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1271
|
+
} else {
|
|
1272
|
+
goalTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
if (team.isPK) {
|
|
1276
|
+
return `[当前战况]
|
|
1277
|
+
攻击方:
|
|
1278
|
+
` + selfTemp.join("\n") + "\n\n防御方:\n" + goalTemp.join("\n");
|
|
1279
|
+
}
|
|
1280
|
+
return `[当前战况]
|
|
1281
|
+
我方阵容:
|
|
1282
|
+
` + selfTemp.join("\n") + "\n\n敌方阵容:\n" + goalTemp.join("\n");
|
|
1283
|
+
},
|
|
1284
|
+
/** 判断输赢 */
|
|
1285
|
+
playOver(team) {
|
|
1286
|
+
const self = team.self.every((item) => item.hp <= 0);
|
|
1287
|
+
const goal = team.goal.every((item) => item.hp <= 0);
|
|
1288
|
+
if (self && goal) {
|
|
1289
|
+
return { over: true, type: "平局", win: "" };
|
|
1290
|
+
} else if (self) {
|
|
1291
|
+
return { over: true, type: team.isPK ? "防御方赢" : "敌方赢", win: "goal" };
|
|
1292
|
+
} else if (goal) {
|
|
1293
|
+
return { over: true, type: team.isPK ? "攻击方赢" : "我方赢", win: "self" };
|
|
1468
1294
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1295
|
+
return { over: false, type: "未结束", win: "" };
|
|
1296
|
+
},
|
|
1297
|
+
/** 清理战场 */
|
|
1298
|
+
clearBattleData(session) {
|
|
1299
|
+
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1300
|
+
const allAgentList = [...currentBattle.goal, ...currentBattle.self];
|
|
1301
|
+
allAgentList.forEach((item) => {
|
|
1302
|
+
if (item.type == "玩家") {
|
|
1303
|
+
delete BattleData.lastPlay[item.userId];
|
|
1473
1304
|
}
|
|
1474
1305
|
});
|
|
1475
|
-
return teamList;
|
|
1476
1306
|
},
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
if (BattleData.isTeamByUserId(userId)) {
|
|
1481
|
-
await session.send(`${User.getUserName(userId)}:你已经加入了${BattleData.teamTemp[userId].for}的队伍,需要退出才可以重新创建!`);
|
|
1307
|
+
async play(session, atkType, select) {
|
|
1308
|
+
if (!BattleData.isBattle(session)) {
|
|
1309
|
+
await session.send("您并没有任何参与战斗。");
|
|
1482
1310
|
return;
|
|
1483
1311
|
}
|
|
1484
|
-
BattleData.
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1312
|
+
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1313
|
+
const allAgentList = [...currentBattle.goal, ...currentBattle.self].sort((a, b) => b.speed + b.gain.speed - (a.speed + a.gain.speed));
|
|
1314
|
+
const msgList = [];
|
|
1315
|
+
for (const agent of allAgentList) {
|
|
1316
|
+
const buffMsg = settlementBuff(agent);
|
|
1317
|
+
buffMsg && msgList.push(buffMsg);
|
|
1318
|
+
if (agent.hp <= 0) {
|
|
1319
|
+
if (agent.type == "玩家" && !User.userTempData[agent.userId]?.isDie) {
|
|
1320
|
+
User.userTempData[agent.userId].hp = 0;
|
|
1321
|
+
User.userTempData[agent.userId].isDie = true;
|
|
1322
|
+
}
|
|
1323
|
+
continue;
|
|
1324
|
+
}
|
|
1325
|
+
if (!agent.gain.dizziness) {
|
|
1326
|
+
let lifeGoalList = [];
|
|
1327
|
+
let lifeSelfList = [];
|
|
1328
|
+
if (agent.for == "self") {
|
|
1329
|
+
lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1330
|
+
lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1331
|
+
} else {
|
|
1332
|
+
lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1333
|
+
lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1334
|
+
}
|
|
1335
|
+
if (!lifeGoalList.length) continue;
|
|
1336
|
+
let selectGoal = {};
|
|
1337
|
+
let isMy = false;
|
|
1338
|
+
let funType = "普攻";
|
|
1339
|
+
if (!agent.gain.chaos) {
|
|
1340
|
+
if (agent.type == "玩家" && agent.userId == session.userId) {
|
|
1341
|
+
isMy = true;
|
|
1342
|
+
funType = atkType;
|
|
1343
|
+
selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1344
|
+
} else if (agent.type == "玩家") {
|
|
1345
|
+
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1346
|
+
} else {
|
|
1347
|
+
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1348
|
+
if (random(0, 10) < 4 && agent.fn?.length) {
|
|
1349
|
+
funType = getSkillFn(agent.fn);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
} else {
|
|
1353
|
+
const fliteMyList = allAgentList.filter((item) => item.id !== agent.id && item.hp > 0);
|
|
1354
|
+
if (!fliteMyList.length) continue;
|
|
1355
|
+
selectGoal = fliteMyList[Math.random() * fliteMyList.length];
|
|
1356
|
+
}
|
|
1357
|
+
const noralAtk = /* @__PURE__ */ __name(() => {
|
|
1358
|
+
const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
|
|
1359
|
+
giveDamage(agent, selectGoal, damageInfo);
|
|
1360
|
+
msgList.push(
|
|
1361
|
+
`${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
|
|
1362
|
+
);
|
|
1363
|
+
}, "noralAtk");
|
|
1364
|
+
if (funType == "普攻") {
|
|
1365
|
+
noralAtk();
|
|
1366
|
+
} else {
|
|
1367
|
+
if (skillFn[funType]) {
|
|
1368
|
+
let _selectGoal = selectGoal;
|
|
1369
|
+
if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[funType].type)) {
|
|
1370
|
+
_selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
|
|
1371
|
+
}
|
|
1372
|
+
const selectFn = skillFn[funType];
|
|
1373
|
+
if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
|
|
1374
|
+
agent.mp -= selectFn.mp;
|
|
1375
|
+
let isNext = false;
|
|
1376
|
+
const fnMsg = selectFn.fn(
|
|
1377
|
+
{ self: agent, goal: _selectGoal },
|
|
1378
|
+
{ selfList: lifeSelfList, goalList: lifeGoalList },
|
|
1379
|
+
(val) => {
|
|
1380
|
+
switch (val.type) {
|
|
1381
|
+
case "伤害技" /* 伤害技 */:
|
|
1382
|
+
val.target.map((goal) => {
|
|
1383
|
+
giveDamage(agent, goal, val.damage);
|
|
1384
|
+
});
|
|
1385
|
+
break;
|
|
1386
|
+
case "治疗技" /* 治疗技 */:
|
|
1387
|
+
val.target.map((goal) => {
|
|
1388
|
+
giveCure(goal, val.value);
|
|
1389
|
+
});
|
|
1390
|
+
break;
|
|
1391
|
+
case "增益技" /* 增益技 */:
|
|
1392
|
+
isMy && val.err && session.send(val.err);
|
|
1393
|
+
break;
|
|
1394
|
+
case "释放失败" /* 释放失败 */:
|
|
1395
|
+
isMy && val.err && session.send(val.err);
|
|
1396
|
+
default:
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
isNext = val.isNext;
|
|
1400
|
+
}
|
|
1401
|
+
);
|
|
1402
|
+
fnMsg && msgList.push(fnMsg);
|
|
1403
|
+
isNext && noralAtk();
|
|
1404
|
+
} else {
|
|
1405
|
+
isMy && await session.send(`MP不足,释放失败!`);
|
|
1406
|
+
noralAtk();
|
|
1407
|
+
}
|
|
1408
|
+
} else {
|
|
1409
|
+
isMy && await session.send(`未持有该技能或者该技能不存在,释放失败!`);
|
|
1410
|
+
noralAtk();
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1496
1414
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1415
|
+
await session.send(msgList.length ? `战斗记录:
|
|
1416
|
+
` + msgList.join("\n") : "");
|
|
1417
|
+
await session.send(BattleData.battleSituationTextFormat(currentBattle));
|
|
1418
|
+
const result = BattleData.playOver(currentBattle);
|
|
1419
|
+
if (result.over) {
|
|
1420
|
+
await session.send(result.type);
|
|
1421
|
+
await BattleData.settlement(currentBattle, result, session);
|
|
1422
|
+
BattleData.clearBattleData(session);
|
|
1501
1423
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1424
|
+
},
|
|
1425
|
+
/** 结算奖励 */
|
|
1426
|
+
async settlement(tempData, overInfo, session) {
|
|
1427
|
+
const allList = [...tempData.self, ...tempData.goal].filter((item) => item.type == "玩家");
|
|
1428
|
+
const selfList = tempData.self.filter((item) => item.type == "玩家");
|
|
1429
|
+
const goalList = tempData.goal.filter((item) => item.type == "玩家");
|
|
1430
|
+
const msg = /* @__PURE__ */ __name(async (val) => {
|
|
1431
|
+
const msgTemp = `${val.name}[升级]${val.lv}级!
|
|
1432
|
+
` + (val.atk ? `攻击力↑ ${val.atk}
|
|
1433
|
+
` : "") + (val.def ? `防御力↑ ${val.def}
|
|
1434
|
+
` : "") + (val.maxHp ? `最大血量↑ ${val.maxHp}
|
|
1435
|
+
` : "") + (val.maxMp ? `最大蓝量↑ ${val.maxMp}` : "");
|
|
1436
|
+
await session.send(msgTemp);
|
|
1437
|
+
}, "msg");
|
|
1438
|
+
const aynchronize = /* @__PURE__ */ __name((agent) => {
|
|
1439
|
+
User.userTempData[agent.userId].hp = agent.hp > 0 ? agent.hp : 0;
|
|
1440
|
+
User.userTempData[agent.userId].mp = agent.mp;
|
|
1441
|
+
if (User.userTempData[agent.userId].hp <= 0) {
|
|
1442
|
+
User.userTempData[agent.userId].isDie = true;
|
|
1443
|
+
}
|
|
1444
|
+
}, "aynchronize");
|
|
1445
|
+
if (tempData.isPK) {
|
|
1446
|
+
if (overInfo.win == "self") {
|
|
1447
|
+
await session.send("攻击方获得20EXP、5货币");
|
|
1448
|
+
for (const agent of allList) {
|
|
1449
|
+
aynchronize(agent);
|
|
1450
|
+
if (agent.for == "self") {
|
|
1451
|
+
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1452
|
+
await User.giveMonetary(agent.userId, 5);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
} else if (overInfo.win == "goal") {
|
|
1456
|
+
await session.send("防御方获得20EXP、5货币");
|
|
1457
|
+
for (const agent of allList) {
|
|
1458
|
+
aynchronize(agent);
|
|
1459
|
+
if (agent.for == "goal") {
|
|
1460
|
+
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1461
|
+
await User.giveMonetary(agent.userId, 5);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
} else {
|
|
1466
|
+
let val = 0;
|
|
1467
|
+
let monetary = 0;
|
|
1468
|
+
let props = [];
|
|
1469
|
+
const monsterName = tempData.goal.filter((item) => item.type == "怪物").map((i) => ({ name: i.name, lv: i.lv }));
|
|
1470
|
+
monsterName.forEach((item) => {
|
|
1471
|
+
const monster = Monster.monsterTempData[item.name];
|
|
1472
|
+
if (monster) {
|
|
1473
|
+
val += Math.floor(monster.giveExp + monster.giveExp * (item.lv - 1) * 0.2);
|
|
1474
|
+
monetary += Math.floor(monster.giveMonetary + monster.giveExp * (item.lv - 1) * 0.1);
|
|
1475
|
+
monster.giveProps?.forEach((propsItem) => {
|
|
1476
|
+
if (item.lv >= (propsItem.lv || 1) && random(0, 100) < propsItem.radomVal) {
|
|
1477
|
+
props.push({
|
|
1478
|
+
name: propsItem.name,
|
|
1479
|
+
val: propsItem.const ? propsItem.val : random(1, propsItem.val)
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1485
|
+
if (overInfo.win == "self") {
|
|
1486
|
+
await session.send(`小队获得${val}EXP、${monetary}货币!`);
|
|
1487
|
+
}
|
|
1488
|
+
for (const agent of selfList) {
|
|
1489
|
+
aynchronize(agent);
|
|
1490
|
+
if (overInfo.win == "self") {
|
|
1491
|
+
await User.giveExp(agent.userId, val, async (val2) => await msg(val2));
|
|
1492
|
+
await User.giveMonetary(agent.userId, monetary);
|
|
1493
|
+
props.length && await User.giveProps(agent.userId, props, async (val2) => {
|
|
1494
|
+
const propsDict = {};
|
|
1495
|
+
val2.currentProps.forEach((item) => {
|
|
1496
|
+
if (!propsDict[item.name]) propsDict[item.name] = 0;
|
|
1497
|
+
propsDict[item.name]++;
|
|
1498
|
+
});
|
|
1499
|
+
const msg2 = Object.keys(propsDict).map((item) => {
|
|
1500
|
+
return `${item} ${propsDict[item]}个`;
|
|
1501
|
+
}).join("\n");
|
|
1502
|
+
await session.send(`${agent.name}在战斗中获得:` + msg2);
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1507
1506
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1507
|
+
}
|
|
1508
|
+
};
|
|
1509
|
+
function getLineupName(agent) {
|
|
1510
|
+
return `[${agent.type}]${agent.name}`;
|
|
1511
|
+
}
|
|
1512
|
+
__name(getLineupName, "getLineupName");
|
|
1513
|
+
function getSkillFn(fnList) {
|
|
1514
|
+
const totalProb = fnList.reduce((sum, item) => sum + item.prob, 0);
|
|
1515
|
+
const random2 = Math.random() * totalProb;
|
|
1516
|
+
let currentProb = 0;
|
|
1517
|
+
for (const item of fnList) {
|
|
1518
|
+
currentProb += item.prob;
|
|
1519
|
+
if (random2 < currentProb) {
|
|
1520
|
+
return item.name;
|
|
1511
1521
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1522
|
+
}
|
|
1523
|
+
return fnList[fnList.length - 1].name;
|
|
1524
|
+
}
|
|
1525
|
+
__name(getSkillFn, "getSkillFn");
|
|
1526
|
+
function initBattleAttribute(data) {
|
|
1527
|
+
if ("playName" in data) {
|
|
1528
|
+
const userData = data;
|
|
1529
|
+
const temp = {
|
|
1530
|
+
id: Date.now(),
|
|
1531
|
+
userId: userData.userId,
|
|
1532
|
+
name: userData.playName,
|
|
1533
|
+
lv: userData.lv,
|
|
1534
|
+
type: "玩家",
|
|
1535
|
+
selfType: userData.type,
|
|
1536
|
+
hp: userData.hp,
|
|
1537
|
+
maxHp: userData.maxHp,
|
|
1538
|
+
mp: userData.mp,
|
|
1539
|
+
maxMp: userData.maxMp,
|
|
1540
|
+
atk: userData.atk,
|
|
1541
|
+
def: userData.def,
|
|
1542
|
+
chr: userData.chr,
|
|
1543
|
+
ghd: userData.ghd,
|
|
1544
|
+
csr: userData.csr,
|
|
1545
|
+
evasion: userData.evasion,
|
|
1546
|
+
hit: userData.hit,
|
|
1547
|
+
speed: userData.speed,
|
|
1548
|
+
gain: {
|
|
1549
|
+
maxHp: 0,
|
|
1550
|
+
maxMp: 0,
|
|
1551
|
+
atk: 0,
|
|
1552
|
+
def: 0,
|
|
1553
|
+
chr: 0,
|
|
1554
|
+
ghd: 0,
|
|
1555
|
+
evasion: 0,
|
|
1556
|
+
hit: 0,
|
|
1557
|
+
speed: 0,
|
|
1558
|
+
chaos: false,
|
|
1559
|
+
dizziness: false,
|
|
1560
|
+
reduction: 0
|
|
1561
|
+
},
|
|
1562
|
+
buff: {},
|
|
1563
|
+
fn: [],
|
|
1564
|
+
expand: {}
|
|
1517
1565
|
};
|
|
1518
|
-
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1566
|
+
return temp;
|
|
1567
|
+
} else {
|
|
1568
|
+
const monsterData2 = data;
|
|
1569
|
+
const temp = {
|
|
1570
|
+
id: Date.now(),
|
|
1571
|
+
name: monsterData2.name,
|
|
1572
|
+
type: "怪物",
|
|
1573
|
+
selfType: monsterData2.type,
|
|
1574
|
+
lv: monsterData2.lv,
|
|
1575
|
+
hp: monsterData2.hp,
|
|
1576
|
+
maxHp: monsterData2.maxHp,
|
|
1577
|
+
mp: monsterData2.mp,
|
|
1578
|
+
maxMp: monsterData2.maxMp,
|
|
1579
|
+
atk: monsterData2.atk,
|
|
1580
|
+
def: monsterData2.def,
|
|
1581
|
+
chr: monsterData2.chr,
|
|
1582
|
+
ghd: monsterData2.ghd,
|
|
1583
|
+
csr: monsterData2.csr,
|
|
1584
|
+
evasion: monsterData2.evasion,
|
|
1585
|
+
hit: monsterData2.hit,
|
|
1586
|
+
speed: monsterData2.speed,
|
|
1587
|
+
gain: {
|
|
1588
|
+
maxHp: 0,
|
|
1589
|
+
maxMp: 0,
|
|
1590
|
+
atk: 0,
|
|
1591
|
+
def: 0,
|
|
1592
|
+
chr: 0,
|
|
1593
|
+
ghd: 0,
|
|
1594
|
+
evasion: 0,
|
|
1595
|
+
hit: 0,
|
|
1596
|
+
speed: 0,
|
|
1597
|
+
chaos: false,
|
|
1598
|
+
dizziness: false,
|
|
1599
|
+
reduction: 0
|
|
1600
|
+
},
|
|
1601
|
+
buff: {},
|
|
1602
|
+
fn: monsterData2.fn ? JSON.parse(JSON.stringify(monsterData2.fn)) : [],
|
|
1603
|
+
expand: {}
|
|
1544
1604
|
};
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
},
|
|
1563
|
-
/** 解散队伍 */
|
|
1564
|
-
async dissolveTeam(session) {
|
|
1565
|
-
const { userId } = session;
|
|
1566
|
-
if (!BattleData.isTeamByUserId(userId)) {
|
|
1567
|
-
await session.send("你还没有加入任何队伍!");
|
|
1568
|
-
return;
|
|
1569
|
-
}
|
|
1570
|
-
if (BattleData.teamTemp[userId].identity == "队员") {
|
|
1571
|
-
await session.send("你不是小队队长,无法解散。");
|
|
1572
|
-
return;
|
|
1573
|
-
}
|
|
1574
|
-
const team = BattleData.teamListByUser(userId);
|
|
1575
|
-
team.forEach((item) => {
|
|
1576
|
-
delete BattleData.teamTemp[item.userId];
|
|
1577
|
-
});
|
|
1578
|
-
await session.send("操作成功,已经解散你创建的小队。");
|
|
1579
|
-
},
|
|
1580
|
-
/** 创建战斗-与怪物 */
|
|
1581
|
-
async createBattleByMonster(session, goal) {
|
|
1582
|
-
if (BattleData.isBattle(session)) {
|
|
1583
|
-
await session.send("当前正在战斗,还不能逃脱!");
|
|
1584
|
-
return;
|
|
1585
|
-
}
|
|
1586
|
-
const battle_user = [];
|
|
1587
|
-
const battle_monsterList = [];
|
|
1588
|
-
const playUser = [];
|
|
1589
|
-
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1590
|
-
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1591
|
-
return;
|
|
1592
|
-
} else if (BattleData.isTeam(session)) {
|
|
1593
|
-
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1594
|
-
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1595
|
-
playUser.push(item);
|
|
1596
|
-
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1605
|
+
return temp;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
__name(initBattleAttribute, "initBattleAttribute");
|
|
1609
|
+
|
|
1610
|
+
// src/data/initProps.ts
|
|
1611
|
+
var propsData = {
|
|
1612
|
+
"红药": {
|
|
1613
|
+
name: "红药",
|
|
1614
|
+
type: "消耗类" /* 消耗类 */,
|
|
1615
|
+
info: "回复自身20HP",
|
|
1616
|
+
price: 10,
|
|
1617
|
+
fn: /* @__PURE__ */ __name(async function(session) {
|
|
1618
|
+
User.giveHPMP(session.userId, { hp: 20 }, async (val) => {
|
|
1619
|
+
if (val.err) {
|
|
1620
|
+
await session.send(val.err);
|
|
1621
|
+
return;
|
|
1597
1622
|
}
|
|
1623
|
+
const msg = `回复成功,玩家当前血量:${val.currentHP}`;
|
|
1624
|
+
await session.send(msg);
|
|
1598
1625
|
});
|
|
1599
|
-
}
|
|
1600
|
-
playUser.push(session.userId);
|
|
1601
|
-
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
1602
|
-
}
|
|
1603
|
-
goal.forEach((item) => {
|
|
1604
|
-
battle_monsterList.push(initBattleAttribute(Monster.getMonsterAttributeData(item.name, item.lv)));
|
|
1605
|
-
});
|
|
1606
|
-
const temp = {
|
|
1607
|
-
self: battle_user.map((i) => ({ ...i, for: "self" })),
|
|
1608
|
-
goal: battle_monsterList.map((i) => ({ ...i, for: "goal" }))
|
|
1609
|
-
};
|
|
1610
|
-
playUser.forEach((userId) => {
|
|
1611
|
-
BattleData.lastPlay[userId] = temp;
|
|
1612
|
-
});
|
|
1613
|
-
await session.send(`开始与 ${goal.map((i) => i.name).join("、")} 进行战斗`);
|
|
1626
|
+
}, "fn")
|
|
1614
1627
|
},
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
goal = goal.filter((item) => {
|
|
1626
|
-
const isBattle = BattleData.isBattleByUserId(item.userId);
|
|
1627
|
-
const pyUser = User.userTempData[item.userId];
|
|
1628
|
-
if (isBattle) {
|
|
1629
|
-
lostMsg.push(`${pyUser.playName}正在参与着一场战斗,无法被PK选中。`);
|
|
1630
|
-
return false;
|
|
1631
|
-
}
|
|
1632
|
-
return true;
|
|
1633
|
-
});
|
|
1634
|
-
if (lostMsg.length) {
|
|
1635
|
-
await session.send(lostMsg.join("\n"));
|
|
1636
|
-
}
|
|
1637
|
-
if (!goal.length) {
|
|
1638
|
-
lostMsg.push(`PK失败,无任何目标进行PK`);
|
|
1639
|
-
return;
|
|
1640
|
-
}
|
|
1641
|
-
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1642
|
-
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1643
|
-
return;
|
|
1644
|
-
} else if (BattleData.isTeam(session)) {
|
|
1645
|
-
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1646
|
-
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1647
|
-
playUser.push(item);
|
|
1648
|
-
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1628
|
+
"蓝药": {
|
|
1629
|
+
name: "蓝药",
|
|
1630
|
+
type: "消耗类" /* 消耗类 */,
|
|
1631
|
+
info: "回复自身20MP",
|
|
1632
|
+
price: 10,
|
|
1633
|
+
fn: /* @__PURE__ */ __name(async function(session) {
|
|
1634
|
+
User.giveHPMP(session.userId, { mp: 20 }, async (val) => {
|
|
1635
|
+
if (val.err) {
|
|
1636
|
+
await session.send(val.err);
|
|
1637
|
+
return;
|
|
1649
1638
|
}
|
|
1639
|
+
const msg = `回复成功,玩家当前蓝量:${val.currentMP}`;
|
|
1640
|
+
await session.send(msg);
|
|
1650
1641
|
});
|
|
1651
|
-
}
|
|
1652
|
-
playUser.push(session.userId);
|
|
1653
|
-
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
1654
|
-
}
|
|
1655
|
-
goal.forEach((item) => {
|
|
1656
|
-
playUser.push(item.userId);
|
|
1657
|
-
battle_goal.push(initBattleAttribute(User.getUserAttributeByUserId(item.userId)));
|
|
1658
|
-
});
|
|
1659
|
-
const pkTemp = {
|
|
1660
|
-
self: battle_self.map((i) => ({ ...i, for: "self" })),
|
|
1661
|
-
goal: battle_goal.map((i) => ({ ...i, for: "goal" })),
|
|
1662
|
-
isPK: true
|
|
1663
|
-
};
|
|
1664
|
-
playUser.forEach((userId) => {
|
|
1665
|
-
BattleData.lastPlay[userId] = pkTemp;
|
|
1666
|
-
});
|
|
1667
|
-
await session.send(`开始与玩家 ${battle_goal.map((i) => i.name).join("、")} 进行PK战斗`);
|
|
1642
|
+
}, "fn")
|
|
1668
1643
|
},
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1644
|
+
"初级万能药": {
|
|
1645
|
+
name: "初级万能药",
|
|
1646
|
+
type: "消耗类" /* 消耗类 */,
|
|
1647
|
+
info: "回复自身20MP和20HP",
|
|
1648
|
+
price: 20,
|
|
1649
|
+
fn: /* @__PURE__ */ __name(async function(session) {
|
|
1650
|
+
User.giveHPMP(session.userId, { hp: 20, mp: 20 }, async (val) => {
|
|
1651
|
+
if (val.err) {
|
|
1652
|
+
await session.send(val.err);
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
const msg = `回复成功,玩家当前血量:${val.currentHP}、蓝量:${val.currentMP}`;
|
|
1656
|
+
await session.send(msg);
|
|
1677
1657
|
});
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1658
|
+
}, "fn")
|
|
1659
|
+
},
|
|
1660
|
+
"初级复活卷轴": {
|
|
1661
|
+
name: "初级复活卷轴",
|
|
1662
|
+
type: "消耗类" /* 消耗类 */,
|
|
1663
|
+
info: "复活玩家,复活时保留 20% 血量。(该道具使用完需要冷却 6 分钟)",
|
|
1664
|
+
price: 10,
|
|
1665
|
+
cooling: 3600,
|
|
1666
|
+
fn: /* @__PURE__ */ __name(async function(session) {
|
|
1667
|
+
if (BattleData.isBattleByUserId(session.userId)) {
|
|
1668
|
+
session.send(`该道具在战斗中无法使用!请在小队脱离战斗后使用。`);
|
|
1669
|
+
return { err: true };
|
|
1687
1670
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
goalTemp.push(`lv.${item.lv}[${item.name}]${getBuffTemplate(item)}:
|
|
1692
|
-
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1693
|
-
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1694
|
-
} else {
|
|
1695
|
-
goalTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1671
|
+
if (!User.isDie(session.userId)) {
|
|
1672
|
+
session.send(`您还没有阵亡,使用失败!`);
|
|
1673
|
+
return { err: true };
|
|
1696
1674
|
}
|
|
1675
|
+
const { maxHp } = User.getUserAttributeByUserId(session.userId);
|
|
1676
|
+
User.giveLife(session.userId, Math.floor(maxHp * 0.2), async (val) => {
|
|
1677
|
+
await session.send(`复活成功,当前血量:${val.currentHP}`);
|
|
1678
|
+
});
|
|
1679
|
+
}, "fn")
|
|
1680
|
+
}
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1683
|
+
// src/props.ts
|
|
1684
|
+
var Props = {
|
|
1685
|
+
config: {},
|
|
1686
|
+
ctx: {},
|
|
1687
|
+
userPorpsTemp: {},
|
|
1688
|
+
async init(config, ctx) {
|
|
1689
|
+
Props.config = config;
|
|
1690
|
+
Props.ctx = ctx;
|
|
1691
|
+
ctx.database.extend("smm_gensokyo_user_props", {
|
|
1692
|
+
userId: "string",
|
|
1693
|
+
props: "json"
|
|
1694
|
+
}, {
|
|
1695
|
+
primary: "userId",
|
|
1696
|
+
autoInc: false
|
|
1697
1697
|
});
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
}
|
|
1703
|
-
return `[当前战况]
|
|
1704
|
-
我方阵容:
|
|
1705
|
-
` + selfTemp.join("\n") + "\n\n敌方阵容:\n" + goalTemp.join("\n");
|
|
1706
|
-
},
|
|
1707
|
-
/** 判断输赢 */
|
|
1708
|
-
playOver(team) {
|
|
1709
|
-
const self = team.self.every((item) => item.hp <= 0);
|
|
1710
|
-
const goal = team.goal.every((item) => item.hp <= 0);
|
|
1711
|
-
if (self && goal) {
|
|
1712
|
-
return { over: true, type: "平局", win: "" };
|
|
1713
|
-
} else if (self) {
|
|
1714
|
-
return { over: true, type: team.isPK ? "防御方赢" : "敌方赢", win: "goal" };
|
|
1715
|
-
} else if (goal) {
|
|
1716
|
-
return { over: true, type: team.isPK ? "攻击方赢" : "我方赢", win: "self" };
|
|
1717
|
-
}
|
|
1718
|
-
return { over: false, type: "未结束", win: "" };
|
|
1719
|
-
},
|
|
1720
|
-
/** 清理战场 */
|
|
1721
|
-
clearBattleData(session) {
|
|
1722
|
-
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1723
|
-
const allAgentList = [...currentBattle.goal, ...currentBattle.self];
|
|
1724
|
-
allAgentList.forEach((item) => {
|
|
1725
|
-
if (item.type == "玩家") {
|
|
1726
|
-
delete BattleData.lastPlay[item.userId];
|
|
1727
|
-
}
|
|
1698
|
+
const temp = {};
|
|
1699
|
+
const propsList = await ctx.database.get("smm_gensokyo_user_props", {});
|
|
1700
|
+
propsList.forEach((item) => {
|
|
1701
|
+
temp[item.userId] = item.props;
|
|
1728
1702
|
});
|
|
1703
|
+
Props.userPorpsTemp = temp;
|
|
1729
1704
|
},
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
const buffMsg = settlementBuff(agent);
|
|
1740
|
-
buffMsg && msgList.push(buffMsg);
|
|
1741
|
-
if (agent.hp <= 0) {
|
|
1742
|
-
if (agent.type == "玩家" && !User.userTempData[agent.userId]?.isDie) {
|
|
1743
|
-
User.userTempData[agent.userId].hp = 0;
|
|
1744
|
-
User.userTempData[agent.userId].isDie = true;
|
|
1745
|
-
}
|
|
1746
|
-
continue;
|
|
1747
|
-
}
|
|
1748
|
-
if (!agent.gain.dizziness) {
|
|
1749
|
-
let lifeGoalList = [];
|
|
1750
|
-
let lifeSelfList = [];
|
|
1751
|
-
if (agent.for == "self") {
|
|
1752
|
-
lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1753
|
-
lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1754
|
-
} else {
|
|
1755
|
-
lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1756
|
-
lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1757
|
-
}
|
|
1758
|
-
if (!lifeGoalList.length) continue;
|
|
1759
|
-
let selectGoal = {};
|
|
1760
|
-
let isMy = false;
|
|
1761
|
-
let funType = "普攻";
|
|
1762
|
-
if (!agent.gain.chaos) {
|
|
1763
|
-
if (agent.type == "玩家" && agent.userId == session.userId) {
|
|
1764
|
-
isMy = true;
|
|
1765
|
-
funType = atkType;
|
|
1766
|
-
selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1767
|
-
} else if (agent.type == "玩家") {
|
|
1768
|
-
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1769
|
-
} else {
|
|
1770
|
-
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1771
|
-
if (random(0, 10) < 4 && agent.fn?.length) {
|
|
1772
|
-
funType = getSkillFn(agent.fn);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
} else {
|
|
1776
|
-
const fliteMyList = allAgentList.filter((item) => item.id !== agent.id && item.hp > 0);
|
|
1777
|
-
if (!fliteMyList.length) continue;
|
|
1778
|
-
selectGoal = fliteMyList[Math.random() * fliteMyList.length];
|
|
1779
|
-
}
|
|
1780
|
-
const noralAtk = /* @__PURE__ */ __name(() => {
|
|
1781
|
-
const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
|
|
1782
|
-
giveDamage(agent, selectGoal, damageInfo);
|
|
1783
|
-
msgList.push(
|
|
1784
|
-
`${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
|
|
1785
|
-
);
|
|
1786
|
-
}, "noralAtk");
|
|
1787
|
-
if (funType == "普攻") {
|
|
1788
|
-
noralAtk();
|
|
1789
|
-
} else {
|
|
1790
|
-
if (skillFn[funType]) {
|
|
1791
|
-
let _selectGoal = selectGoal;
|
|
1792
|
-
if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[funType].type)) {
|
|
1793
|
-
_selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
|
|
1794
|
-
}
|
|
1795
|
-
const selectFn = skillFn[funType];
|
|
1796
|
-
if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
|
|
1797
|
-
agent.mp -= selectFn.mp;
|
|
1798
|
-
let isNext = false;
|
|
1799
|
-
const fnMsg = selectFn.fn(
|
|
1800
|
-
{ self: agent, goal: _selectGoal },
|
|
1801
|
-
{ selfList: lifeSelfList, goalList: lifeGoalList },
|
|
1802
|
-
(val) => {
|
|
1803
|
-
switch (val.type) {
|
|
1804
|
-
case "伤害技" /* 伤害技 */:
|
|
1805
|
-
val.target.map((goal) => {
|
|
1806
|
-
giveDamage(agent, goal, val.damage);
|
|
1807
|
-
});
|
|
1808
|
-
break;
|
|
1809
|
-
case "治疗技" /* 治疗技 */:
|
|
1810
|
-
val.target.map((goal) => {
|
|
1811
|
-
giveCure(goal, val.value);
|
|
1812
|
-
});
|
|
1813
|
-
break;
|
|
1814
|
-
case "增益技" /* 增益技 */:
|
|
1815
|
-
isMy && val.err && session.send(val.err);
|
|
1816
|
-
break;
|
|
1817
|
-
case "释放失败" /* 释放失败 */:
|
|
1818
|
-
isMy && val.err && session.send(val.err);
|
|
1819
|
-
default:
|
|
1820
|
-
break;
|
|
1821
|
-
}
|
|
1822
|
-
isNext = val.isNext;
|
|
1823
|
-
}
|
|
1824
|
-
);
|
|
1825
|
-
fnMsg && msgList.push(fnMsg);
|
|
1826
|
-
isNext && noralAtk();
|
|
1827
|
-
} else {
|
|
1828
|
-
isMy && await session.send(`MP不足,释放失败!`);
|
|
1829
|
-
noralAtk();
|
|
1830
|
-
}
|
|
1831
|
-
} else {
|
|
1832
|
-
isMy && await session.send(`未持有该技能或者该技能不存在,释放失败!`);
|
|
1833
|
-
noralAtk();
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
}
|
|
1838
|
-
await session.send(msgList.length ? `战斗记录:
|
|
1839
|
-
` + msgList.join("\n") : "");
|
|
1840
|
-
await session.send(BattleData.battleSituationTextFormat(currentBattle));
|
|
1841
|
-
const result = BattleData.playOver(currentBattle);
|
|
1842
|
-
if (result.over) {
|
|
1843
|
-
await session.send(result.type);
|
|
1844
|
-
await BattleData.settlement(currentBattle, result, session);
|
|
1845
|
-
BattleData.clearBattleData(session);
|
|
1705
|
+
/** 创建本地数据 */
|
|
1706
|
+
async initUserPropsData(userId) {
|
|
1707
|
+
if (!Props.userPorpsTemp[userId]) {
|
|
1708
|
+
Props.userPorpsTemp[userId] = {};
|
|
1709
|
+
const temp = {
|
|
1710
|
+
userId,
|
|
1711
|
+
props: {}
|
|
1712
|
+
};
|
|
1713
|
+
await Props.ctx.database.create("smm_gensokyo_user_props", temp);
|
|
1846
1714
|
}
|
|
1847
1715
|
},
|
|
1848
|
-
/**
|
|
1849
|
-
async
|
|
1850
|
-
|
|
1851
|
-
const
|
|
1852
|
-
const
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
`
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
const
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1716
|
+
/** 获取持有道具信息 */
|
|
1717
|
+
async getPropsDataByUserId(userId) {
|
|
1718
|
+
await Props.initUserPropsData(userId);
|
|
1719
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
1720
|
+
const msgList = Object.keys(userProps).map((item) => {
|
|
1721
|
+
return `${userProps[item].name}:${userProps[item].value}个`;
|
|
1722
|
+
});
|
|
1723
|
+
return msgList.length ? `当前您持有如下道具:
|
|
1724
|
+
|
|
1725
|
+
` + msgList.join("\n") : "您没有任何道具...";
|
|
1726
|
+
},
|
|
1727
|
+
/** 更新本地数据库对应数据 */
|
|
1728
|
+
async setDatabasePropsData(userId) {
|
|
1729
|
+
const propsData2 = Props.userPorpsTemp[userId];
|
|
1730
|
+
if (propsData2) {
|
|
1731
|
+
const temp = {
|
|
1732
|
+
props: propsData2
|
|
1733
|
+
};
|
|
1734
|
+
await Props.ctx.database.set("smm_gensokyo_user_props", { userId }, temp);
|
|
1735
|
+
}
|
|
1736
|
+
},
|
|
1737
|
+
/** 使用指定道具 */
|
|
1738
|
+
async userProps(session, propsName) {
|
|
1739
|
+
const userId = session.userId;
|
|
1740
|
+
const userPropsData = Props.userPorpsTemp[userId];
|
|
1741
|
+
if (!userPropsData) return;
|
|
1742
|
+
if (!userPropsData[propsName]) {
|
|
1743
|
+
await session.send(`您似乎没有${propsName}这个道具...`);
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
if (propsData[propsName].cooling) {
|
|
1747
|
+
if (!coolingTemp[userId]) coolingTemp[userId] = {};
|
|
1748
|
+
if (!coolingTemp[userId][propsName]) coolingTemp[userId][propsName] = 0;
|
|
1749
|
+
const gapTime = Date.now() - coolingTemp[userId][propsName];
|
|
1750
|
+
if (gapTime < propsData[propsName].cooling) {
|
|
1751
|
+
await session.send(`该道具冷却还未结束,请等待${Math.ceil((coolingTemp[userId][propsName] - gapTime) / 60)}秒!`);
|
|
1752
|
+
return;
|
|
1753
|
+
} else {
|
|
1754
|
+
coolingTemp[userId][propsName] = Date.now();
|
|
1866
1755
|
}
|
|
1867
|
-
}
|
|
1868
|
-
|
|
1869
|
-
if (
|
|
1870
|
-
await session.send(
|
|
1871
|
-
|
|
1872
|
-
aynchronize(agent);
|
|
1873
|
-
if (agent.for == "self") {
|
|
1874
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1875
|
-
await User.giveMonetary(agent.userId, 5);
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
} else if (overInfo.win == "goal") {
|
|
1879
|
-
await session.send("防御方获得20EXP、5货币");
|
|
1880
|
-
for (const agent of allList) {
|
|
1881
|
-
aynchronize(agent);
|
|
1882
|
-
if (agent.for == "goal") {
|
|
1883
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1884
|
-
await User.giveMonetary(agent.userId, 5);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1756
|
+
}
|
|
1757
|
+
User.loseProps(userId, { name: propsName, val: 1 }, async (val) => {
|
|
1758
|
+
if (val.err) {
|
|
1759
|
+
await session.send(val.err);
|
|
1760
|
+
return;
|
|
1887
1761
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
if (monster) {
|
|
1896
|
-
val += Math.floor(monster.giveExp + monster.giveExp * (item.lv - 1) * 0.2);
|
|
1897
|
-
monetary += Math.floor(monster.giveMonetary + monster.giveExp * (item.lv - 1) * 0.1);
|
|
1898
|
-
monster.giveProps?.forEach((propsItem) => {
|
|
1899
|
-
if (item.lv >= (propsItem.lv || 1) && random(0, 100) < propsItem.radomVal) {
|
|
1900
|
-
props.push({
|
|
1901
|
-
name: propsItem.name,
|
|
1902
|
-
val: propsItem.const ? propsItem.val : random(1, propsItem.val)
|
|
1903
|
-
});
|
|
1904
|
-
}
|
|
1905
|
-
});
|
|
1762
|
+
if (propsData[propsName].cooling) {
|
|
1763
|
+
coolingTemp[userId];
|
|
1764
|
+
}
|
|
1765
|
+
const result = await propsData[propsName].fn(session);
|
|
1766
|
+
if (result && typeof result === "object" && "err" in result) {
|
|
1767
|
+
if (result.err) {
|
|
1768
|
+
await User.giveProps(userId, [{ name: propsName, val: 1 }]);
|
|
1906
1769
|
}
|
|
1907
|
-
});
|
|
1908
|
-
if (overInfo.win == "self") {
|
|
1909
|
-
await session.send(`小队获得${val}EXP、${monetary}货币!`);
|
|
1910
1770
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
};
|
|
1774
|
+
var coolingTemp = {};
|
|
1775
|
+
|
|
1776
|
+
// src/users.ts
|
|
1777
|
+
var UserOccDict = {
|
|
1778
|
+
["剑士" /* 剑士 */]: {
|
|
1779
|
+
info: "擅长近战攻击,拥有强大的属性能力",
|
|
1780
|
+
initStatus: {
|
|
1781
|
+
userId: "",
|
|
1782
|
+
playName: "",
|
|
1783
|
+
type: "剑士" /* 剑士 */,
|
|
1784
|
+
exp: 0,
|
|
1785
|
+
maxExp: 100,
|
|
1786
|
+
lv: 1,
|
|
1787
|
+
hp: 120,
|
|
1788
|
+
maxHp: 120,
|
|
1789
|
+
mp: 80,
|
|
1790
|
+
maxMp: 80,
|
|
1791
|
+
pp: 100,
|
|
1792
|
+
maxPp: 100,
|
|
1793
|
+
atk: 12,
|
|
1794
|
+
def: 5,
|
|
1795
|
+
chr: 50,
|
|
1796
|
+
csr: 0,
|
|
1797
|
+
ghd: 1.2,
|
|
1798
|
+
speed: 5,
|
|
1799
|
+
evasion: 100,
|
|
1800
|
+
hit: 100
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
["法师" /* 法师 */]: {
|
|
1804
|
+
info: "精通元素魔法,能够打出爆发伤害",
|
|
1805
|
+
initStatus: {
|
|
1806
|
+
userId: "",
|
|
1807
|
+
playName: "",
|
|
1808
|
+
type: "法师" /* 法师 */,
|
|
1809
|
+
exp: 0,
|
|
1810
|
+
maxExp: 100,
|
|
1811
|
+
lv: 1,
|
|
1812
|
+
hp: 100,
|
|
1813
|
+
maxHp: 100,
|
|
1814
|
+
mp: 100,
|
|
1815
|
+
maxMp: 100,
|
|
1816
|
+
pp: 100,
|
|
1817
|
+
maxPp: 100,
|
|
1818
|
+
atk: 10,
|
|
1819
|
+
def: 2,
|
|
1820
|
+
chr: 50,
|
|
1821
|
+
csr: 0,
|
|
1822
|
+
ghd: 1.2,
|
|
1823
|
+
speed: 5,
|
|
1824
|
+
evasion: 100,
|
|
1825
|
+
hit: 100
|
|
1826
|
+
}
|
|
1827
|
+
},
|
|
1828
|
+
["刺客" /* 刺客 */]: {
|
|
1829
|
+
info: "迅捷攻击,高闪避值的高敏玩家",
|
|
1830
|
+
initStatus: {
|
|
1831
|
+
userId: "",
|
|
1832
|
+
playName: "",
|
|
1833
|
+
type: "刺客" /* 刺客 */,
|
|
1834
|
+
exp: 0,
|
|
1835
|
+
maxExp: 100,
|
|
1836
|
+
lv: 1,
|
|
1837
|
+
hp: 90,
|
|
1838
|
+
maxHp: 90,
|
|
1839
|
+
mp: 70,
|
|
1840
|
+
maxMp: 70,
|
|
1841
|
+
pp: 100,
|
|
1842
|
+
maxPp: 100,
|
|
1843
|
+
atk: 8,
|
|
1844
|
+
def: 2,
|
|
1845
|
+
chr: 80,
|
|
1846
|
+
csr: 0,
|
|
1847
|
+
ghd: 1.3,
|
|
1848
|
+
speed: 6,
|
|
1849
|
+
evasion: 120,
|
|
1850
|
+
hit: 100
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
};
|
|
1854
|
+
var User = {
|
|
1855
|
+
config: {},
|
|
1856
|
+
ctx: {},
|
|
1857
|
+
userTempData: {},
|
|
1858
|
+
async init(config, ctx) {
|
|
1859
|
+
User.config = config;
|
|
1860
|
+
User.ctx = ctx;
|
|
1861
|
+
ctx.model.extend(
|
|
1862
|
+
"smm_gensokyo_user_attribute",
|
|
1863
|
+
{
|
|
1864
|
+
userId: "string",
|
|
1865
|
+
playName: "string",
|
|
1866
|
+
type: "string",
|
|
1867
|
+
exp: "integer",
|
|
1868
|
+
lv: "integer",
|
|
1869
|
+
hp: "integer",
|
|
1870
|
+
mp: "integer",
|
|
1871
|
+
pp: "integer",
|
|
1872
|
+
isDie: "boolean"
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
primary: "userId",
|
|
1876
|
+
autoInc: false
|
|
1877
|
+
}
|
|
1878
|
+
);
|
|
1879
|
+
const userData = await ctx.database.get("smm_gensokyo_user_attribute", {});
|
|
1880
|
+
const temp = {};
|
|
1881
|
+
userData.forEach((item) => {
|
|
1882
|
+
temp[item.userId] = item;
|
|
1883
|
+
});
|
|
1884
|
+
User.userTempData = temp;
|
|
1885
|
+
},
|
|
1886
|
+
/** 获取玩家名字 */
|
|
1887
|
+
getUserName(userId) {
|
|
1888
|
+
return User.userTempData[userId].playName || null;
|
|
1889
|
+
},
|
|
1890
|
+
/** 获取角色基础属性 */
|
|
1891
|
+
async getUserAttribute(session) {
|
|
1892
|
+
if (!User.userTempData[session.userId]) {
|
|
1893
|
+
await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
|
|
1894
|
+
return null;
|
|
1895
|
+
}
|
|
1896
|
+
return User.getUserAddLvAttribute(session.userId);
|
|
1897
|
+
},
|
|
1898
|
+
/** 获取角色实际等级属性数据 */
|
|
1899
|
+
getUserAddLvAttribute(userId) {
|
|
1900
|
+
const UserDict = User.userTempData[userId];
|
|
1901
|
+
if (!UserDict) return null;
|
|
1902
|
+
const UserData = {
|
|
1903
|
+
...UserOccDict[UserDict.type].initStatus,
|
|
1904
|
+
lv: UserDict.lv,
|
|
1905
|
+
hp: UserDict.hp,
|
|
1906
|
+
mp: UserDict.mp,
|
|
1907
|
+
exp: UserDict.exp,
|
|
1908
|
+
pp: UserDict.pp,
|
|
1909
|
+
playName: UserDict.playName,
|
|
1910
|
+
userId: UserDict.userId
|
|
1911
|
+
};
|
|
1912
|
+
const lv = UserData.lv;
|
|
1913
|
+
const temp = {};
|
|
1914
|
+
const lvScope = Object.keys(userBenchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
1915
|
+
const useBenchmark = userBenchmark[lvScope];
|
|
1916
|
+
Object.keys(UserData).forEach((i) => {
|
|
1917
|
+
temp[i] = UserData[i];
|
|
1918
|
+
if (useBenchmark[i]) {
|
|
1919
|
+
if (i == "maxExp") {
|
|
1920
|
+
temp[i] = Math.floor(100 * useBenchmark[i] * (lv - 1)) || 100;
|
|
1921
|
+
} else {
|
|
1922
|
+
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
1927
1923
|
}
|
|
1928
1924
|
}
|
|
1925
|
+
});
|
|
1926
|
+
return temp;
|
|
1927
|
+
},
|
|
1928
|
+
/** 通过 userId 获取角色属性 */
|
|
1929
|
+
getUserAttributeByUserId(userId) {
|
|
1930
|
+
return User.getUserAddLvAttribute(userId) || null;
|
|
1931
|
+
},
|
|
1932
|
+
/** 创建游戏账号 */
|
|
1933
|
+
async createPlayUser(session) {
|
|
1934
|
+
const [data] = await User.ctx.database.get("smm_gensokyo_user_attribute", { userId: session.userId });
|
|
1935
|
+
if (data) {
|
|
1936
|
+
await session.send("已存在账号,请勿重复创建!");
|
|
1937
|
+
return;
|
|
1929
1938
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
if (
|
|
1943
|
-
|
|
1939
|
+
await session.send("请输入自己的游戏昵称:(60s)");
|
|
1940
|
+
const playname = await session.prompt(6e4);
|
|
1941
|
+
if (playname == void 0) return;
|
|
1942
|
+
const [repeat] = await User.ctx.database.get("smm_gensokyo_user_attribute", { playName: playname.trim() });
|
|
1943
|
+
if (repeat) {
|
|
1944
|
+
await session.send("名字重复,请更换一个名字。");
|
|
1945
|
+
return;
|
|
1946
|
+
}
|
|
1947
|
+
if (Object.keys(monsterData).includes(playname?.trim())) {
|
|
1948
|
+
await session.send("请不要设置怪物的名字!");
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
if (playname.trim().length > 6 || playname.trim().length < 1) {
|
|
1952
|
+
await session.send("名字长度有问题,要求小于 6个字,大于 1个字");
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1955
|
+
await session.send(`请输入要专职的职业:(60s)
|
|
1956
|
+
${Object.keys(UserOccDict).map((i) => `【${i}】:${UserOccDict[i].info}`).join("\n")}`);
|
|
1957
|
+
let jobType = await session.prompt(6e4);
|
|
1958
|
+
if (jobType == void 0) return;
|
|
1959
|
+
while (!Object.keys(UserOccDict).includes(jobType)) {
|
|
1960
|
+
await session.send("未找到该职业,请重新选择!");
|
|
1961
|
+
jobType = await session.prompt(6e4);
|
|
1944
1962
|
}
|
|
1945
|
-
}
|
|
1946
|
-
return fnList[fnList.length - 1].name;
|
|
1947
|
-
}
|
|
1948
|
-
__name(getSkillFn, "getSkillFn");
|
|
1949
|
-
function initBattleAttribute(data) {
|
|
1950
|
-
if ("playName" in data) {
|
|
1951
|
-
const userData = data;
|
|
1952
1963
|
const temp = {
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
maxMp: userData.maxMp,
|
|
1963
|
-
atk: userData.atk,
|
|
1964
|
-
def: userData.def,
|
|
1965
|
-
chr: userData.chr,
|
|
1966
|
-
ghd: userData.ghd,
|
|
1967
|
-
csr: userData.csr,
|
|
1968
|
-
evasion: userData.evasion,
|
|
1969
|
-
hit: userData.hit,
|
|
1970
|
-
speed: userData.speed,
|
|
1971
|
-
gain: {
|
|
1972
|
-
maxHp: 0,
|
|
1973
|
-
maxMp: 0,
|
|
1974
|
-
atk: 0,
|
|
1975
|
-
def: 0,
|
|
1976
|
-
chr: 0,
|
|
1977
|
-
ghd: 0,
|
|
1978
|
-
evasion: 0,
|
|
1979
|
-
hit: 0,
|
|
1980
|
-
speed: 0,
|
|
1981
|
-
chaos: false,
|
|
1982
|
-
dizziness: false,
|
|
1983
|
-
reduction: 0
|
|
1984
|
-
},
|
|
1985
|
-
buff: {},
|
|
1986
|
-
fn: [],
|
|
1987
|
-
expand: {}
|
|
1964
|
+
userId: session.userId,
|
|
1965
|
+
playName: playname.trim(),
|
|
1966
|
+
type: jobType,
|
|
1967
|
+
hp: UserOccDict[jobType].initStatus.hp,
|
|
1968
|
+
pp: UserOccDict[jobType].initStatus.pp,
|
|
1969
|
+
mp: UserOccDict[jobType].initStatus.mp,
|
|
1970
|
+
lv: 1,
|
|
1971
|
+
exp: 0,
|
|
1972
|
+
isDie: false
|
|
1988
1973
|
};
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1974
|
+
User.ctx.database.create("smm_gensokyo_user_attribute", temp);
|
|
1975
|
+
User.userTempData[session.userId] = temp;
|
|
1976
|
+
await Props.initUserPropsData(session.userId);
|
|
1977
|
+
await session.send("创建成功!\n" + User.userAttributeTextFormat(session.userId));
|
|
1978
|
+
},
|
|
1979
|
+
/** 信息格式化 */
|
|
1980
|
+
userAttributeTextFormat(userId) {
|
|
1981
|
+
if (!User.userTempData[userId]) {
|
|
1982
|
+
return "没有找到您的角色信息";
|
|
1983
|
+
}
|
|
1984
|
+
const temp = User.getUserAttributeByUserId(userId);
|
|
1985
|
+
return `昵称:${temp.playName}
|
|
1986
|
+
职位:${temp.type}
|
|
1987
|
+
等级:${temp.lv} (${temp.exp}/${temp.maxExp})
|
|
1988
|
+
-----------------
|
|
1989
|
+
【生命值】${temp.hp}/${temp.maxHp}
|
|
1990
|
+
【魔法值】${temp.mp}/${temp.maxMp}
|
|
1991
|
+
【活力值】${temp.pp}/${temp.maxPp}
|
|
1992
|
+
-----------------
|
|
1993
|
+
【攻击力】${temp.atk} (+0)
|
|
1994
|
+
【防御力】${temp.def} (+0)
|
|
1995
|
+
【速度值】${temp.speed} (+0)
|
|
1996
|
+
【闪避值】${temp.evasion} (+0)
|
|
1997
|
+
【命中率】${(temp.hit / 10 + 100).toFixed(1)}% (+0%)
|
|
1998
|
+
【暴击率】${(temp.chr / 10).toFixed(1)}% (+0%)
|
|
1999
|
+
【暴击伤害】${(temp.ghd * 100).toFixed(1)}% (+0%)` + (temp.csr > 0 ? `
|
|
2000
|
+
【暴击抵抗】${temp.csr}` : "");
|
|
2001
|
+
},
|
|
2002
|
+
/** 写入用户数据到数据库 */
|
|
2003
|
+
async setDatabaseUserAttribute(userId) {
|
|
2004
|
+
const userInfo = User.userTempData[userId];
|
|
2005
|
+
if (!userInfo) return;
|
|
1992
2006
|
const temp = {
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
lv:
|
|
1998
|
-
|
|
1999
|
-
maxHp: monsterData2.maxHp,
|
|
2000
|
-
mp: monsterData2.mp,
|
|
2001
|
-
maxMp: monsterData2.maxMp,
|
|
2002
|
-
atk: monsterData2.atk,
|
|
2003
|
-
def: monsterData2.def,
|
|
2004
|
-
chr: monsterData2.chr,
|
|
2005
|
-
ghd: monsterData2.ghd,
|
|
2006
|
-
csr: monsterData2.csr,
|
|
2007
|
-
evasion: monsterData2.evasion,
|
|
2008
|
-
hit: monsterData2.hit,
|
|
2009
|
-
speed: monsterData2.speed,
|
|
2010
|
-
gain: {
|
|
2011
|
-
maxHp: 0,
|
|
2012
|
-
maxMp: 0,
|
|
2013
|
-
atk: 0,
|
|
2014
|
-
def: 0,
|
|
2015
|
-
chr: 0,
|
|
2016
|
-
ghd: 0,
|
|
2017
|
-
evasion: 0,
|
|
2018
|
-
hit: 0,
|
|
2019
|
-
speed: 0,
|
|
2020
|
-
chaos: false,
|
|
2021
|
-
dizziness: false,
|
|
2022
|
-
reduction: 0
|
|
2023
|
-
},
|
|
2024
|
-
buff: {},
|
|
2025
|
-
fn: monsterData2.fn ? JSON.parse(JSON.stringify(monsterData2.fn)) : [],
|
|
2026
|
-
expand: {}
|
|
2007
|
+
playName: userInfo.playName.trim(),
|
|
2008
|
+
hp: userInfo.hp,
|
|
2009
|
+
pp: userInfo.pp,
|
|
2010
|
+
mp: userInfo.mp,
|
|
2011
|
+
lv: userInfo.lv,
|
|
2012
|
+
exp: userInfo.exp
|
|
2027
2013
|
};
|
|
2028
|
-
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2014
|
+
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
2015
|
+
},
|
|
2016
|
+
/** 给予玩家经验 */
|
|
2017
|
+
async giveExp(userId, value, fn) {
|
|
2018
|
+
const userInfo = User.userTempData[userId];
|
|
2019
|
+
if (!userInfo) return;
|
|
2020
|
+
const beforData = { ...User.getUserAttributeByUserId(userId) };
|
|
2021
|
+
let isUp = false;
|
|
2022
|
+
userInfo.exp += value;
|
|
2023
|
+
while (true) {
|
|
2024
|
+
const { maxExp } = User.getUserAttributeByUserId(userId);
|
|
2025
|
+
if (userInfo.exp < maxExp) break;
|
|
2026
|
+
userInfo.lv += 1;
|
|
2027
|
+
userInfo.exp -= maxExp;
|
|
2028
|
+
isUp = true;
|
|
2029
|
+
}
|
|
2030
|
+
if (isUp) {
|
|
2031
|
+
const afterData = User.getUserAttributeByUserId(userId);
|
|
2032
|
+
const upTemp = {
|
|
2033
|
+
name: afterData.playName,
|
|
2034
|
+
lv: afterData.lv,
|
|
2035
|
+
maxHp: afterData.maxHp - beforData.maxHp,
|
|
2036
|
+
maxMp: afterData.maxMp = beforData.maxMp,
|
|
2037
|
+
atk: afterData.atk - beforData.atk,
|
|
2038
|
+
def: afterData.def - beforData.def
|
|
2039
|
+
};
|
|
2040
|
+
fn && await fn(upTemp);
|
|
2041
|
+
}
|
|
2042
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2043
|
+
},
|
|
2044
|
+
/** 给予玩家死亡 */
|
|
2045
|
+
async giveDie(userId) {
|
|
2046
|
+
const userInfo = User.userTempData[userId];
|
|
2047
|
+
userInfo.hp = 0;
|
|
2048
|
+
userInfo.isDie = true;
|
|
2049
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2050
2050
|
},
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
const msg = `回复成功,玩家当前蓝量:${val.currentMP}`;
|
|
2063
|
-
await session.send(msg);
|
|
2064
|
-
});
|
|
2065
|
-
}, "fn")
|
|
2051
|
+
/** 给予玩家复活 */
|
|
2052
|
+
async giveLife(userId, val, fn) {
|
|
2053
|
+
const userInfo = User.userTempData[userId];
|
|
2054
|
+
if (!val) {
|
|
2055
|
+
const { maxHp } = User.getUserAttributeByUserId(userId);
|
|
2056
|
+
userInfo.hp = maxHp;
|
|
2057
|
+
} else {
|
|
2058
|
+
userInfo.hp = val;
|
|
2059
|
+
}
|
|
2060
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2061
|
+
fn && await fn({ currentHP: userInfo.hp });
|
|
2066
2062
|
},
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
return;
|
|
2077
|
-
}
|
|
2078
|
-
const msg = `回复成功,玩家当前血量:${val.currentHP}、蓝量:${val.currentMP}`;
|
|
2079
|
-
await session.send(msg);
|
|
2063
|
+
/** 给予玩家血量或者蓝量 */
|
|
2064
|
+
async giveHPMP(userId, value, fn) {
|
|
2065
|
+
const userInfo = User.userTempData[userId];
|
|
2066
|
+
if (!userInfo) return;
|
|
2067
|
+
if (userInfo.isDie) {
|
|
2068
|
+
fn && await fn({
|
|
2069
|
+
currentHP: 0,
|
|
2070
|
+
currentMP: 0,
|
|
2071
|
+
err: "角色已死亡,无法使用恢复道具。"
|
|
2080
2072
|
});
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
return { err: true };
|
|
2073
|
+
return;
|
|
2074
|
+
}
|
|
2075
|
+
if (BattleData.isBattleByUserId(userId)) {
|
|
2076
|
+
const { goal, self } = BattleData.lastPlay[userId];
|
|
2077
|
+
const agentAll = [...goal, ...self];
|
|
2078
|
+
const agent = agentAll.find((item) => item?.userId == userId);
|
|
2079
|
+
if (!agent) return;
|
|
2080
|
+
if (agent.hp + (value.hp || 0) < agent.maxHp) {
|
|
2081
|
+
agent.hp += value.hp || 0;
|
|
2082
|
+
} else {
|
|
2083
|
+
agent.hp = agent.maxHp;
|
|
2093
2084
|
}
|
|
2094
|
-
if (
|
|
2095
|
-
|
|
2096
|
-
|
|
2085
|
+
if (agent.mp + (value.mp || 0) < agent.maxMp) {
|
|
2086
|
+
agent.mp += value.mp || 0;
|
|
2087
|
+
} else {
|
|
2088
|
+
agent.mp = agent.maxMp;
|
|
2097
2089
|
}
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2090
|
+
fn && await fn({
|
|
2091
|
+
currentHP: agent.hp,
|
|
2092
|
+
currentMP: agent.mp
|
|
2101
2093
|
});
|
|
2102
|
-
|
|
2103
|
-
}
|
|
2104
|
-
};
|
|
2105
|
-
|
|
2106
|
-
// src/props.ts
|
|
2107
|
-
var Props = {
|
|
2108
|
-
config: {},
|
|
2109
|
-
ctx: {},
|
|
2110
|
-
userPorpsTemp: {},
|
|
2111
|
-
async init(config, ctx) {
|
|
2112
|
-
Props.config = config;
|
|
2113
|
-
Props.ctx = ctx;
|
|
2114
|
-
ctx.database.extend("smm_gensokyo_user_props", {
|
|
2115
|
-
userId: "string",
|
|
2116
|
-
props: "json"
|
|
2117
|
-
}, {
|
|
2118
|
-
primary: "userId",
|
|
2119
|
-
autoInc: false
|
|
2120
|
-
});
|
|
2121
|
-
const temp = {};
|
|
2122
|
-
const propsList = await ctx.database.get("smm_gensokyo_user_props", {});
|
|
2123
|
-
propsList.forEach((item) => {
|
|
2124
|
-
temp[item.userId] = item.props;
|
|
2125
|
-
});
|
|
2126
|
-
Props.userPorpsTemp = temp;
|
|
2127
|
-
},
|
|
2128
|
-
/** 创建本地数据 */
|
|
2129
|
-
async initUserPropsData(userId) {
|
|
2130
|
-
if (!Props.userPorpsTemp[userId]) {
|
|
2131
|
-
Props.userPorpsTemp[userId] = {};
|
|
2132
|
-
const temp = {
|
|
2133
|
-
userId,
|
|
2134
|
-
props: {}
|
|
2135
|
-
};
|
|
2136
|
-
await Props.ctx.database.create("smm_gensokyo_user_props", temp);
|
|
2094
|
+
return;
|
|
2137
2095
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2096
|
+
const { maxHp, maxMp } = User.getUserAttributeByUserId(userId);
|
|
2097
|
+
if (value.hp && !value.mp && userInfo.hp == maxHp) {
|
|
2098
|
+
fn && await fn({
|
|
2099
|
+
currentHP: userInfo.hp,
|
|
2100
|
+
currentMP: userInfo.mp,
|
|
2101
|
+
err: "当前血量已满,无需回复。"
|
|
2102
|
+
});
|
|
2103
|
+
return;
|
|
2104
|
+
}
|
|
2105
|
+
if (value.mp && !value.hp && userInfo.mp == maxMp) {
|
|
2106
|
+
fn && await fn({
|
|
2107
|
+
currentHP: userInfo.hp,
|
|
2108
|
+
currentMP: userInfo.mp,
|
|
2109
|
+
err: "当前蓝量已满,无需回复。"
|
|
2110
|
+
});
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
2113
|
+
if (value.mp && value.hp && userInfo.mp == maxMp && userInfo.hp == maxHp) {
|
|
2114
|
+
fn && await fn({
|
|
2115
|
+
currentHP: userInfo.hp,
|
|
2116
|
+
currentMP: userInfo.mp,
|
|
2117
|
+
err: "当前状态全满,无需回复。"
|
|
2118
|
+
});
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
if (userInfo.hp + (value.hp || 0) < maxHp) {
|
|
2122
|
+
userInfo.hp += value.hp || 0;
|
|
2123
|
+
} else {
|
|
2124
|
+
userInfo.hp = maxHp;
|
|
2125
|
+
}
|
|
2126
|
+
if (userInfo.mp + (value.mp || 0) < maxHp) {
|
|
2127
|
+
userInfo.mp += value.mp || 0;
|
|
2128
|
+
} else {
|
|
2129
|
+
userInfo.mp = maxMp;
|
|
2130
|
+
}
|
|
2131
|
+
fn && await fn({
|
|
2132
|
+
currentHP: userInfo.hp,
|
|
2133
|
+
currentMP: userInfo.mp
|
|
2145
2134
|
});
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
` + msgList.join("\n") : "您没有任何道具...";
|
|
2135
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2149
2136
|
},
|
|
2150
|
-
/**
|
|
2151
|
-
async
|
|
2152
|
-
const
|
|
2153
|
-
if (
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2137
|
+
/** 给予玩家PP值 */
|
|
2138
|
+
async givePP(userId, value, fn) {
|
|
2139
|
+
const userInfo = User.userTempData[userId];
|
|
2140
|
+
if (!userInfo) return;
|
|
2141
|
+
const { maxPp } = User.getUserAttributeByUserId(userId);
|
|
2142
|
+
if (userInfo.pp + value < maxPp) {
|
|
2143
|
+
userInfo.pp += value;
|
|
2144
|
+
} else {
|
|
2145
|
+
userInfo.pp = maxPp;
|
|
2158
2146
|
}
|
|
2147
|
+
fn && await fn({
|
|
2148
|
+
currentPP: userInfo.pp
|
|
2149
|
+
});
|
|
2150
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2159
2151
|
},
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2152
|
+
async lostPP(userId, value, fn) {
|
|
2153
|
+
const userInfo = User.userTempData[userId];
|
|
2154
|
+
if (!userInfo) return;
|
|
2155
|
+
if (userInfo.pp - value < 0) {
|
|
2156
|
+
fn && await fn({
|
|
2157
|
+
currentPP: userInfo.pp,
|
|
2158
|
+
err: "PP值不够,消耗失败!"
|
|
2159
|
+
});
|
|
2167
2160
|
return;
|
|
2168
2161
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2162
|
+
userInfo.pp -= value;
|
|
2163
|
+
fn && await fn({
|
|
2164
|
+
currentPP: userInfo.pp
|
|
2165
|
+
});
|
|
2166
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2167
|
+
},
|
|
2168
|
+
/** 给予玩家货币 */
|
|
2169
|
+
async giveMonetary(userId, val, fn) {
|
|
2170
|
+
const [bindData] = await User.ctx.database.get("binding", { pid: userId });
|
|
2171
|
+
if (bindData && val) {
|
|
2172
|
+
const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
|
|
2173
|
+
await User.ctx.monetary.gain(bindData.aid, val);
|
|
2174
|
+
fn && await fn({ val, currentVal: currentM.value += val });
|
|
2179
2175
|
}
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2176
|
+
},
|
|
2177
|
+
/** 收取玩家货币 */
|
|
2178
|
+
async lostMonetary(userId, val, fn) {
|
|
2179
|
+
const [bindData] = await User.ctx.database.get("binding", { pid: userId });
|
|
2180
|
+
if (bindData && val) {
|
|
2181
|
+
const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
|
|
2182
|
+
if (currentM.value - val < 0) {
|
|
2183
|
+
fn && await fn({
|
|
2184
|
+
val: Math.abs(val),
|
|
2185
|
+
currentVal: currentM.value,
|
|
2186
|
+
err: "余额不足!"
|
|
2187
|
+
});
|
|
2188
|
+
return;
|
|
2193
2189
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
// src/users.ts
|
|
2200
|
-
var UserOccDict = {
|
|
2201
|
-
["剑士" /* 剑士 */]: {
|
|
2202
|
-
info: "擅长近战攻击,拥有强大的属性能力",
|
|
2203
|
-
initStatus: {
|
|
2204
|
-
userId: "",
|
|
2205
|
-
playName: "",
|
|
2206
|
-
type: "剑士" /* 剑士 */,
|
|
2207
|
-
exp: 0,
|
|
2208
|
-
maxExp: 100,
|
|
2209
|
-
lv: 1,
|
|
2210
|
-
hp: 120,
|
|
2211
|
-
maxHp: 120,
|
|
2212
|
-
mp: 80,
|
|
2213
|
-
maxMp: 80,
|
|
2214
|
-
pp: 100,
|
|
2215
|
-
maxPp: 100,
|
|
2216
|
-
atk: 12,
|
|
2217
|
-
def: 5,
|
|
2218
|
-
chr: 50,
|
|
2219
|
-
csr: 0,
|
|
2220
|
-
ghd: 1.2,
|
|
2221
|
-
speed: 5,
|
|
2222
|
-
evasion: 100,
|
|
2223
|
-
hit: 100
|
|
2190
|
+
await User.ctx.monetary.cost(bindData.aid, val);
|
|
2191
|
+
fn && await fn({
|
|
2192
|
+
val: Math.abs(val),
|
|
2193
|
+
currentVal: currentM.value - val
|
|
2194
|
+
});
|
|
2224
2195
|
}
|
|
2225
2196
|
},
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
chr: 50,
|
|
2244
|
-
csr: 0,
|
|
2245
|
-
ghd: 1.2,
|
|
2246
|
-
speed: 5,
|
|
2247
|
-
evasion: 100,
|
|
2248
|
-
hit: 100
|
|
2197
|
+
/** 给予玩家指定道具 */
|
|
2198
|
+
async giveProps(userId, props, fn) {
|
|
2199
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
2200
|
+
if (!userProps) return;
|
|
2201
|
+
const upProps = [];
|
|
2202
|
+
for (const item of props) {
|
|
2203
|
+
const propsItem = propsData[item.name];
|
|
2204
|
+
if (!propsData[item.name]) continue;
|
|
2205
|
+
if (!userProps[item.name]) {
|
|
2206
|
+
userProps[item.name] = {
|
|
2207
|
+
name: propsItem.name,
|
|
2208
|
+
type: propsItem.type,
|
|
2209
|
+
value: 0
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
userProps[item.name].value += item.val || 1;
|
|
2213
|
+
upProps.push({ name: item.name, val: userProps[item.name].value });
|
|
2249
2214
|
}
|
|
2215
|
+
await Props.setDatabasePropsData(userId);
|
|
2216
|
+
fn && await fn({
|
|
2217
|
+
currentProps: upProps
|
|
2218
|
+
});
|
|
2250
2219
|
},
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2220
|
+
/** 去除玩家指定道具 */
|
|
2221
|
+
async loseProps(userId, props, fn) {
|
|
2222
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
2223
|
+
const propsItem = propsData[props.name];
|
|
2224
|
+
if (!userProps) return;
|
|
2225
|
+
if (!propsItem) {
|
|
2226
|
+
fn && await fn({
|
|
2227
|
+
currentProps: { name: props.name, val: 0 },
|
|
2228
|
+
err: "该道具信息不存在!"
|
|
2229
|
+
});
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
if (!userProps[props.name]) {
|
|
2233
|
+
userProps[props.name] = {
|
|
2234
|
+
name: propsItem.name,
|
|
2235
|
+
type: propsItem.type,
|
|
2236
|
+
value: 0
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
if (userProps[props.name].value - (props.val || 1) < 0) {
|
|
2240
|
+
fn && await fn({
|
|
2241
|
+
currentProps: { name: props.name, val: userProps[props.name].value },
|
|
2242
|
+
err: `道具数量不足!剩余${userProps[props.name].value}个。`
|
|
2243
|
+
});
|
|
2244
|
+
return;
|
|
2274
2245
|
}
|
|
2246
|
+
userProps[props.name].value -= props.val || 1;
|
|
2247
|
+
if (userProps[props.name].value == 0) delete userProps[props.name];
|
|
2248
|
+
await Props.setDatabasePropsData(userId);
|
|
2249
|
+
fn && await fn({
|
|
2250
|
+
currentProps: { name: props.name, val: userProps[props.name]?.value || 0 }
|
|
2251
|
+
});
|
|
2252
|
+
},
|
|
2253
|
+
/** 目标是否死亡 */
|
|
2254
|
+
isDie(userId) {
|
|
2255
|
+
return User.userTempData[userId]?.isDie;
|
|
2275
2256
|
}
|
|
2276
2257
|
};
|
|
2277
|
-
|
|
2258
|
+
|
|
2259
|
+
// src/map.ts
|
|
2260
|
+
var delay = /* @__PURE__ */ __name((ms) => new Promise((resolve) => setTimeout(resolve, ms)), "delay");
|
|
2261
|
+
var GensokyoMap = {
|
|
2278
2262
|
config: {},
|
|
2279
2263
|
ctx: {},
|
|
2280
|
-
|
|
2264
|
+
mapLocalData: {},
|
|
2265
|
+
userCurrentLoal: {},
|
|
2281
2266
|
async init(config, ctx) {
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
ctx.
|
|
2285
|
-
"
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
mp: "integer",
|
|
2294
|
-
pp: "integer",
|
|
2295
|
-
isDie: "boolean"
|
|
2296
|
-
},
|
|
2297
|
-
{
|
|
2298
|
-
primary: "userId",
|
|
2299
|
-
autoInc: false
|
|
2300
|
-
}
|
|
2301
|
-
);
|
|
2302
|
-
const userData = await ctx.database.get("smm_gensokyo_user_attribute", {});
|
|
2303
|
-
const temp = {};
|
|
2304
|
-
userData.forEach((item) => {
|
|
2305
|
-
temp[item.userId] = item;
|
|
2267
|
+
GensokyoMap.config = config;
|
|
2268
|
+
GensokyoMap.ctx = ctx;
|
|
2269
|
+
ctx.database.extend("smm_gensokyo_map_position", {
|
|
2270
|
+
userId: "string",
|
|
2271
|
+
floor: "integer",
|
|
2272
|
+
areaName: "string",
|
|
2273
|
+
moveing: "boolean",
|
|
2274
|
+
playName: "string"
|
|
2275
|
+
}, {
|
|
2276
|
+
primary: "userId",
|
|
2277
|
+
autoInc: false
|
|
2306
2278
|
});
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2279
|
+
GensokyoMap.mapLocalData = {
|
|
2280
|
+
1: {
|
|
2281
|
+
"地下墓穴": {
|
|
2282
|
+
floor: 1,
|
|
2283
|
+
areaName: "地下墓穴",
|
|
2284
|
+
type: "BOSS区" /* BOSS区 */,
|
|
2285
|
+
needLv: 10,
|
|
2286
|
+
down: "蜘蛛洞穴",
|
|
2287
|
+
monster: [{ name: "古明地觉", lv: 15 }]
|
|
2288
|
+
},
|
|
2289
|
+
"蜘蛛洞穴": {
|
|
2290
|
+
floor: 1,
|
|
2291
|
+
areaName: "蜘蛛洞穴",
|
|
2292
|
+
type: "冒险区" /* 冒险区 */,
|
|
2293
|
+
needLv: 1,
|
|
2294
|
+
top: "地下墓穴",
|
|
2295
|
+
down: "蜘蛛森林一"
|
|
2296
|
+
},
|
|
2297
|
+
"蜘蛛森林一": {
|
|
2298
|
+
floor: 1,
|
|
2299
|
+
areaName: "蜘蛛森林一",
|
|
2300
|
+
type: "冒险区" /* 冒险区 */,
|
|
2301
|
+
needLv: 1,
|
|
2302
|
+
monster: [{ name: "小蜘蛛", lv: 2 }],
|
|
2303
|
+
top: "蜘蛛洞穴",
|
|
2304
|
+
left: "蜘蛛森林二",
|
|
2305
|
+
right: "蜘蛛森林三",
|
|
2306
|
+
down: "蜘蛛森林通道"
|
|
2307
|
+
},
|
|
2308
|
+
"蜘蛛森林二": {
|
|
2309
|
+
floor: 1,
|
|
2310
|
+
areaName: "蜘蛛森林二",
|
|
2311
|
+
type: "冒险区" /* 冒险区 */,
|
|
2312
|
+
needLv: 1,
|
|
2313
|
+
right: "蜘蛛森林一"
|
|
2314
|
+
},
|
|
2315
|
+
"蜘蛛森林三": {
|
|
2316
|
+
floor: 1,
|
|
2317
|
+
areaName: "蜘蛛森林三",
|
|
2318
|
+
type: "冒险区" /* 冒险区 */,
|
|
2319
|
+
needLv: 1,
|
|
2320
|
+
left: "蜘蛛森林一",
|
|
2321
|
+
monster: [{ name: "大妖精", lv: 3 }]
|
|
2322
|
+
},
|
|
2323
|
+
"蜘蛛森林通道": {
|
|
2324
|
+
floor: 1,
|
|
2325
|
+
areaName: "蜘蛛森林通道",
|
|
2326
|
+
type: "冒险区" /* 冒险区 */,
|
|
2327
|
+
needLv: 1,
|
|
2328
|
+
top: "蜘蛛森林一",
|
|
2329
|
+
down: "中央广场"
|
|
2330
|
+
},
|
|
2331
|
+
"中央广场": {
|
|
2332
|
+
floor: 1,
|
|
2333
|
+
areaName: "中央广场",
|
|
2334
|
+
info: "一层的中心位置,梦开始的地方",
|
|
2335
|
+
npc: ["aipo"],
|
|
2336
|
+
type: "安全区" /* 安全区 */,
|
|
2337
|
+
needLv: 1,
|
|
2338
|
+
top: "蜘蛛森林通道",
|
|
2339
|
+
down: "新手村",
|
|
2340
|
+
left: "酒馆",
|
|
2341
|
+
right: "银行"
|
|
2342
|
+
},
|
|
2343
|
+
"酒馆": {
|
|
2344
|
+
floor: 1,
|
|
2345
|
+
areaName: "酒馆",
|
|
2346
|
+
type: "安全区" /* 安全区 */,
|
|
2347
|
+
needLv: 1,
|
|
2348
|
+
down: "传送门",
|
|
2349
|
+
right: "中央广场"
|
|
2350
|
+
},
|
|
2351
|
+
"银行": {
|
|
2352
|
+
floor: 1,
|
|
2353
|
+
areaName: "银行",
|
|
2354
|
+
type: "安全区" /* 安全区 */,
|
|
2355
|
+
needLv: 1,
|
|
2356
|
+
down: "1层-商店",
|
|
2357
|
+
left: "中央广场"
|
|
2358
|
+
},
|
|
2359
|
+
"1层-商店": {
|
|
2360
|
+
floor: 1,
|
|
2361
|
+
areaName: "1层-商店",
|
|
2362
|
+
type: "安全区" /* 安全区 */,
|
|
2363
|
+
needLv: 1,
|
|
2364
|
+
right: "农田",
|
|
2365
|
+
left: "新手村"
|
|
2366
|
+
},
|
|
2367
|
+
"传送门": {
|
|
2368
|
+
floor: 1,
|
|
2369
|
+
areaName: "传送门",
|
|
2370
|
+
type: "传送门" /* 传送门 */,
|
|
2371
|
+
needLv: 1,
|
|
2372
|
+
top: "酒馆",
|
|
2373
|
+
right: "新手村",
|
|
2374
|
+
left: "爱之湖"
|
|
2375
|
+
},
|
|
2376
|
+
"爱之湖": {
|
|
2377
|
+
floor: 1,
|
|
2378
|
+
areaName: "传送门",
|
|
2379
|
+
type: "安全区" /* 安全区 */,
|
|
2380
|
+
needLv: 1,
|
|
2381
|
+
right: "传送门"
|
|
2382
|
+
},
|
|
2383
|
+
"新手村": {
|
|
2384
|
+
floor: 1,
|
|
2385
|
+
areaName: "新手村",
|
|
2386
|
+
type: "安全区" /* 安全区 */,
|
|
2387
|
+
needLv: 1,
|
|
2388
|
+
top: "中央广场",
|
|
2389
|
+
down: "绿野平原通道",
|
|
2390
|
+
left: "传送门",
|
|
2391
|
+
right: "1层-商店"
|
|
2392
|
+
},
|
|
2393
|
+
"绿野平原通道": {
|
|
2394
|
+
floor: 1,
|
|
2395
|
+
areaName: "绿野平原通道",
|
|
2396
|
+
type: "安全区" /* 安全区 */,
|
|
2397
|
+
needLv: 1,
|
|
2398
|
+
top: "新手村",
|
|
2399
|
+
down: "绿野平原一"
|
|
2400
|
+
},
|
|
2401
|
+
"绿野平原一": {
|
|
2402
|
+
floor: 1,
|
|
2403
|
+
areaName: "绿野平原一",
|
|
2404
|
+
type: "冒险区" /* 冒险区 */,
|
|
2405
|
+
monster: [{ name: "小蜜蜂", lv: 1 }, { name: "dora", lv: 2 }],
|
|
2406
|
+
needLv: 1,
|
|
2407
|
+
top: "绿野平原通道",
|
|
2408
|
+
left: "绿野平原二",
|
|
2409
|
+
right: "绿野平原三",
|
|
2410
|
+
down: "绿野平原四"
|
|
2411
|
+
},
|
|
2412
|
+
"绿野平原二": {
|
|
2413
|
+
floor: 1,
|
|
2414
|
+
areaName: "绿野平原二",
|
|
2415
|
+
type: "冒险区" /* 冒险区 */,
|
|
2416
|
+
monster: [{ name: "dora", lv: 2 }, { name: "dora", lv: 2 }, { name: "dora", lv: 3 }, { name: "dora", lv: 2 }],
|
|
2417
|
+
needLv: 1,
|
|
2418
|
+
right: "绿野平原一",
|
|
2419
|
+
down: "绿野平原五"
|
|
2420
|
+
},
|
|
2421
|
+
"绿野平原三": {
|
|
2422
|
+
floor: 1,
|
|
2423
|
+
areaName: "绿野平原三",
|
|
2424
|
+
type: "冒险区" /* 冒险区 */,
|
|
2425
|
+
monster: [{ name: "dora", lv: 5 }],
|
|
2426
|
+
needLv: 1,
|
|
2427
|
+
left: "绿野平原一",
|
|
2428
|
+
down: "绿野平原六"
|
|
2429
|
+
},
|
|
2430
|
+
"绿野平原四": {
|
|
2431
|
+
floor: 1,
|
|
2432
|
+
areaName: "绿野平原四",
|
|
2433
|
+
type: "冒险区" /* 冒险区 */,
|
|
2434
|
+
needLv: 1,
|
|
2435
|
+
top: "绿野平原一",
|
|
2436
|
+
down: "野猪巢穴",
|
|
2437
|
+
left: "绿野平原五",
|
|
2438
|
+
right: "绿野平原六",
|
|
2439
|
+
monster: [{ name: "琪露诺", lv: 10 }]
|
|
2440
|
+
},
|
|
2441
|
+
"绿野平原五": {
|
|
2442
|
+
floor: 1,
|
|
2443
|
+
areaName: "绿野平原五",
|
|
2444
|
+
type: "冒险区" /* 冒险区 */,
|
|
2445
|
+
needLv: 1,
|
|
2446
|
+
top: "绿野平原二",
|
|
2447
|
+
right: "绿野平原四"
|
|
2448
|
+
},
|
|
2449
|
+
"绿野平原六": {
|
|
2450
|
+
floor: 1,
|
|
2451
|
+
areaName: "绿野平原六",
|
|
2452
|
+
type: "冒险区" /* 冒险区 */,
|
|
2453
|
+
needLv: 1,
|
|
2454
|
+
left: "绿野平原四",
|
|
2455
|
+
top: "绿野平原三",
|
|
2456
|
+
monster: [{ name: "绿毒蛇", lv: 12 }]
|
|
2457
|
+
},
|
|
2458
|
+
"野猪巢穴": {
|
|
2459
|
+
floor: 1,
|
|
2460
|
+
areaName: "野猪巢穴",
|
|
2461
|
+
type: "BOSS区" /* BOSS区 */,
|
|
2462
|
+
needLv: 15,
|
|
2463
|
+
top: "绿野平原四",
|
|
2464
|
+
monster: [{ name: "蓬莱山辉夜", lv: 20 }]
|
|
2346
2465
|
}
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2466
|
+
},
|
|
2467
|
+
2: {
|
|
2468
|
+
"传送门": {
|
|
2469
|
+
floor: 2,
|
|
2470
|
+
areaName: "传送门",
|
|
2471
|
+
type: "传送门" /* 传送门 */,
|
|
2472
|
+
needLv: 1,
|
|
2473
|
+
right: "希望之泉"
|
|
2474
|
+
},
|
|
2475
|
+
"希望之泉": {
|
|
2476
|
+
floor: 2,
|
|
2477
|
+
areaName: "希望之泉",
|
|
2478
|
+
type: "安全区" /* 安全区 */,
|
|
2479
|
+
needLv: 1,
|
|
2480
|
+
top: "爱之湖",
|
|
2481
|
+
down: "农田",
|
|
2482
|
+
left: "传送门",
|
|
2483
|
+
right: "2层-商店"
|
|
2484
|
+
},
|
|
2485
|
+
"爱之湖": {
|
|
2486
|
+
floor: 2,
|
|
2487
|
+
areaName: "爱之湖",
|
|
2488
|
+
type: "安全区" /* 安全区 */,
|
|
2489
|
+
needLv: 1,
|
|
2490
|
+
down: "希望之泉",
|
|
2491
|
+
right: "旅馆"
|
|
2492
|
+
},
|
|
2493
|
+
"农田": {
|
|
2494
|
+
floor: 2,
|
|
2495
|
+
areaName: "农田",
|
|
2496
|
+
type: "安全区" /* 安全区 */,
|
|
2497
|
+
needLv: 1,
|
|
2498
|
+
top: "希望之泉",
|
|
2499
|
+
right: "银行"
|
|
2500
|
+
},
|
|
2501
|
+
"银行": {
|
|
2502
|
+
floor: 2,
|
|
2503
|
+
areaName: "银行",
|
|
2504
|
+
type: "安全区" /* 安全区 */,
|
|
2505
|
+
needLv: 1,
|
|
2506
|
+
top: "2层-商店",
|
|
2507
|
+
left: "农田"
|
|
2508
|
+
},
|
|
2509
|
+
"旅馆": {
|
|
2510
|
+
floor: 2,
|
|
2511
|
+
areaName: "旅馆",
|
|
2512
|
+
type: "安全区" /* 安全区 */,
|
|
2513
|
+
needLv: 1,
|
|
2514
|
+
down: "2层-商店",
|
|
2515
|
+
left: "爱之湖"
|
|
2516
|
+
},
|
|
2517
|
+
"2层-商店": {
|
|
2518
|
+
floor: 2,
|
|
2519
|
+
areaName: "2层-商店",
|
|
2520
|
+
type: "安全区" /* 安全区 */,
|
|
2521
|
+
needLv: 1,
|
|
2522
|
+
right: "大草场"
|
|
2523
|
+
},
|
|
2524
|
+
"大草场": {
|
|
2525
|
+
floor: 2,
|
|
2526
|
+
areaName: "大草场",
|
|
2527
|
+
type: "安全区" /* 安全区 */,
|
|
2528
|
+
needLv: 1,
|
|
2529
|
+
left: "2层-商店",
|
|
2530
|
+
right: "森林岔口"
|
|
2531
|
+
},
|
|
2532
|
+
"森林岔口": {
|
|
2533
|
+
floor: 2,
|
|
2534
|
+
areaName: "森林岔口",
|
|
2535
|
+
type: "安全区" /* 安全区 */,
|
|
2536
|
+
needLv: 1,
|
|
2537
|
+
left: "大草场"
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2396
2540
|
};
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2541
|
+
console.log(JSON.stringify(GensokyoMap.mapLocalData));
|
|
2542
|
+
const userPoistionList = await ctx.database.get("smm_gensokyo_map_position", {});
|
|
2543
|
+
const poistionTemp = {};
|
|
2544
|
+
userPoistionList.forEach((poistion) => {
|
|
2545
|
+
poistion.moveing = false;
|
|
2546
|
+
poistionTemp[poistion.userId] = poistion;
|
|
2547
|
+
});
|
|
2548
|
+
GensokyoMap.userCurrentLoal = poistionTemp;
|
|
2401
2549
|
},
|
|
2402
|
-
/**
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
return "没有找到您的角色信息";
|
|
2406
|
-
}
|
|
2407
|
-
const temp = User.getUserAttributeByUserId(userId);
|
|
2408
|
-
return `昵称:${temp.playName}
|
|
2409
|
-
职位:${temp.type}
|
|
2410
|
-
等级:${temp.lv} (${temp.exp}/${temp.maxExp})
|
|
2411
|
-
-----------------
|
|
2412
|
-
【生命值】${temp.hp}/${temp.maxHp}
|
|
2413
|
-
【魔法值】${temp.mp}/${temp.maxMp}
|
|
2414
|
-
【活力值】${temp.pp}/${temp.maxPp}
|
|
2415
|
-
-----------------
|
|
2416
|
-
【攻击力】${temp.atk} (+0)
|
|
2417
|
-
【防御力】${temp.def} (+0)
|
|
2418
|
-
【速度值】${temp.speed} (+0)
|
|
2419
|
-
【闪避值】${temp.evasion} (+0)
|
|
2420
|
-
【命中率】${(temp.hit / 10 + 100).toFixed(1)}% (+0%)
|
|
2421
|
-
【暴击率】${(temp.chr / 10).toFixed(1)}% (+0%)
|
|
2422
|
-
【暴击伤害】${(temp.ghd * 100).toFixed(1)}% (+0%)` + (temp.csr > 0 ? `
|
|
2423
|
-
【暴击抵抗】${temp.csr}` : "");
|
|
2550
|
+
/** 获取层的数据 */
|
|
2551
|
+
getBaseFloorLocal(floor) {
|
|
2552
|
+
return GensokyoMap.mapLocalData[floor] || null;
|
|
2424
2553
|
},
|
|
2425
|
-
/**
|
|
2426
|
-
|
|
2427
|
-
const
|
|
2428
|
-
if (!
|
|
2429
|
-
|
|
2430
|
-
playName: userInfo.playName.trim(),
|
|
2431
|
-
hp: userInfo.hp,
|
|
2432
|
-
pp: userInfo.pp,
|
|
2433
|
-
mp: userInfo.mp,
|
|
2434
|
-
lv: userInfo.lv,
|
|
2435
|
-
exp: userInfo.exp
|
|
2436
|
-
};
|
|
2437
|
-
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
2554
|
+
/** 获取用户当前区域信息 */
|
|
2555
|
+
getUserCurrentArea(userid) {
|
|
2556
|
+
const { floor, areaName } = GensokyoMap.userCurrentLoal[userid] || {};
|
|
2557
|
+
if (!(floor && areaName)) return null;
|
|
2558
|
+
return GensokyoMap.mapLocalData[floor][areaName] || null;
|
|
2438
2559
|
},
|
|
2439
|
-
/**
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
if (userInfo.exp < maxExp) break;
|
|
2449
|
-
userInfo.lv += 1;
|
|
2450
|
-
userInfo.exp -= maxExp;
|
|
2451
|
-
isUp = true;
|
|
2452
|
-
}
|
|
2453
|
-
if (isUp) {
|
|
2454
|
-
const afterData = User.getUserAttributeByUserId(userId);
|
|
2455
|
-
const upTemp = {
|
|
2456
|
-
name: afterData.playName,
|
|
2457
|
-
lv: afterData.lv,
|
|
2458
|
-
maxHp: afterData.maxHp - beforData.maxHp,
|
|
2459
|
-
maxMp: afterData.maxMp = beforData.maxMp,
|
|
2460
|
-
atk: afterData.atk - beforData.atk,
|
|
2461
|
-
def: afterData.def - beforData.def
|
|
2560
|
+
/** 初始化用户位置 */
|
|
2561
|
+
initUserPoistion(session, userData) {
|
|
2562
|
+
if (!GensokyoMap.userCurrentLoal[session.userId]) {
|
|
2563
|
+
GensokyoMap.userCurrentLoal[session.userId] = {
|
|
2564
|
+
userId: session.userId,
|
|
2565
|
+
floor: 1,
|
|
2566
|
+
areaName: "传送门",
|
|
2567
|
+
moveing: false,
|
|
2568
|
+
playName: userData.playName
|
|
2462
2569
|
};
|
|
2463
|
-
fn && await fn(upTemp);
|
|
2464
2570
|
}
|
|
2465
|
-
|
|
2466
|
-
},
|
|
2467
|
-
/** 给予玩家死亡 */
|
|
2468
|
-
async giveDie(userId) {
|
|
2469
|
-
const userInfo = User.userTempData[userId];
|
|
2470
|
-
userInfo.hp = 0;
|
|
2471
|
-
userInfo.isDie = true;
|
|
2472
|
-
await User.setDatabaseUserAttribute(userId);
|
|
2571
|
+
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
2473
2572
|
},
|
|
2474
|
-
/**
|
|
2475
|
-
async
|
|
2476
|
-
const
|
|
2477
|
-
if (
|
|
2478
|
-
const
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2573
|
+
/** 位置信息存储到数据库 */
|
|
2574
|
+
async setLocalStoragePoistionData(userId) {
|
|
2575
|
+
const poistionData = { ...GensokyoMap.userCurrentLoal[userId] };
|
|
2576
|
+
if (poistionData) {
|
|
2577
|
+
const [localData] = await GensokyoMap.ctx.database.get("smm_gensokyo_map_position", { userId });
|
|
2578
|
+
if (!localData) {
|
|
2579
|
+
await GensokyoMap.ctx.database.create("smm_gensokyo_map_position", poistionData);
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
delete poistionData.userId;
|
|
2583
|
+
await GensokyoMap.ctx.database.set("smm_gensokyo_map_position", { userId }, poistionData);
|
|
2482
2584
|
}
|
|
2483
|
-
await User.setDatabaseUserAttribute(userId);
|
|
2484
|
-
fn && await fn({ currentHP: userInfo.hp });
|
|
2485
2585
|
},
|
|
2486
|
-
/**
|
|
2487
|
-
async
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
err: "角色已死亡,无法使用恢复道具。"
|
|
2495
|
-
});
|
|
2496
|
-
return;
|
|
2497
|
-
}
|
|
2498
|
-
if (BattleData.isBattleByUserId(userId)) {
|
|
2499
|
-
const { goal, self } = BattleData.lastPlay[userId];
|
|
2500
|
-
const agentAll = [...goal, ...self];
|
|
2501
|
-
const agent = agentAll.find((item) => item?.userId == userId);
|
|
2502
|
-
if (!agent) return;
|
|
2503
|
-
if (agent.hp + (value.hp || 0) < agent.maxHp) {
|
|
2504
|
-
agent.hp += value.hp || 0;
|
|
2505
|
-
} else {
|
|
2506
|
-
agent.hp = agent.maxHp;
|
|
2586
|
+
/** 用户移动 */
|
|
2587
|
+
async move(session, type, fn) {
|
|
2588
|
+
try {
|
|
2589
|
+
const userCurrentArea = GensokyoMap.userCurrentLoal[session.userId] || {};
|
|
2590
|
+
const { floor, areaName, moveing } = userCurrentArea;
|
|
2591
|
+
if (moveing) {
|
|
2592
|
+
await session.send("当前移动冷却中,请稍等...");
|
|
2593
|
+
return;
|
|
2507
2594
|
}
|
|
2508
|
-
if (
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
agent.mp = agent.maxMp;
|
|
2595
|
+
if (!(floor && areaName)) {
|
|
2596
|
+
await session.send("您当前位置有误,请使用(还没写好的指令)脱离卡死...");
|
|
2597
|
+
return;
|
|
2512
2598
|
}
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
}
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2599
|
+
userCurrentArea.moveing = true;
|
|
2600
|
+
const nowPosition = GensokyoMap.mapLocalData[floor][areaName];
|
|
2601
|
+
if (!nowPosition[type]) {
|
|
2602
|
+
await session.send("抱歉,此路不通!");
|
|
2603
|
+
userCurrentArea.moveing = false;
|
|
2604
|
+
return;
|
|
2605
|
+
}
|
|
2606
|
+
const newArea = GensokyoMap.mapLocalData[floor][nowPosition[type]];
|
|
2607
|
+
if (!newArea) {
|
|
2608
|
+
await session.send("进入失败,地图中不存在 " + nowPosition[type] + " 这个区域。");
|
|
2609
|
+
userCurrentArea.moveing = false;
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
if (newArea.type == "禁用" /* 禁用 */) {
|
|
2613
|
+
await session.send(`该区域暂时未开放...`);
|
|
2614
|
+
userCurrentArea.moveing = false;
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
if (newArea.needLv > User.userTempData[session.userId].lv) {
|
|
2618
|
+
await session.send(`当前区域由于您的等级未达到最低要求,暂时无法进入。
|
|
2619
|
+
需要等级:${newArea.needLv}级`);
|
|
2620
|
+
userCurrentArea.moveing = false;
|
|
2621
|
+
return;
|
|
2622
|
+
}
|
|
2623
|
+
if (BattleData.isTeam(session)) {
|
|
2624
|
+
const { userId } = session;
|
|
2625
|
+
const myTeamList = [];
|
|
2626
|
+
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
2627
|
+
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
2628
|
+
myTeamList.push(_userId);
|
|
2629
|
+
}
|
|
2630
|
+
});
|
|
2631
|
+
const belowUser = myTeamList.filter((teamUserId) => newArea.needLv > User.userTempData[teamUserId].lv);
|
|
2632
|
+
if (belowUser.length) {
|
|
2633
|
+
await session.send(
|
|
2634
|
+
`移动失败!队伍存在限制进入等级(lv.${newArea.needLv})玩家,
|
|
2635
|
+
目前限制进入的玩家:
|
|
2636
|
+
${belowUser.map((item) => {
|
|
2637
|
+
return `Lv.${User.userTempData[item].lv} ${User.userTempData[item].playName}`;
|
|
2638
|
+
}).join("\n")}`
|
|
2639
|
+
);
|
|
2640
|
+
userCurrentArea.moveing = false;
|
|
2641
|
+
return;
|
|
2642
|
+
}
|
|
2643
|
+
for (const moveTeamUserId of myTeamList) {
|
|
2644
|
+
GensokyoMap.userCurrentLoal[moveTeamUserId].areaName = newArea.areaName;
|
|
2645
|
+
GensokyoMap.userCurrentLoal[moveTeamUserId].floor = newArea.floor;
|
|
2646
|
+
GensokyoMap.userCurrentLoal[moveTeamUserId].moveing = false;
|
|
2647
|
+
await GensokyoMap.setLocalStoragePoistionData(moveTeamUserId);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
userCurrentArea.areaName = newArea.areaName;
|
|
2651
|
+
const areaInfo = {
|
|
2652
|
+
user: { ...userCurrentArea },
|
|
2653
|
+
map: { ...newArea }
|
|
2654
|
+
};
|
|
2655
|
+
fn && await fn(areaInfo);
|
|
2656
|
+
await delay(3e3);
|
|
2657
|
+
userCurrentArea.moveing = false;
|
|
2658
|
+
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
2542
2659
|
return;
|
|
2660
|
+
} catch (error) {
|
|
2661
|
+
console.log(error);
|
|
2662
|
+
if (GensokyoMap.userCurrentLoal?.[session.userId]) {
|
|
2663
|
+
GensokyoMap.userCurrentLoal[session.userId].moveing = false;
|
|
2664
|
+
}
|
|
2543
2665
|
}
|
|
2544
|
-
if (userInfo.hp + (value.hp || 0) < maxHp) {
|
|
2545
|
-
userInfo.hp += value.hp || 0;
|
|
2546
|
-
} else {
|
|
2547
|
-
userInfo.hp = maxHp;
|
|
2548
|
-
}
|
|
2549
|
-
if (userInfo.mp + (value.mp || 0) < maxHp) {
|
|
2550
|
-
userInfo.mp += value.mp || 0;
|
|
2551
|
-
} else {
|
|
2552
|
-
userInfo.mp = maxMp;
|
|
2553
|
-
}
|
|
2554
|
-
fn && await fn({
|
|
2555
|
-
currentHP: userInfo.hp,
|
|
2556
|
-
currentMP: userInfo.mp
|
|
2557
|
-
});
|
|
2558
|
-
await User.setDatabaseUserAttribute(userId);
|
|
2559
2666
|
},
|
|
2560
|
-
/**
|
|
2561
|
-
|
|
2562
|
-
const
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
currentPP: userInfo.pp
|
|
2667
|
+
/** 查询附近玩家 */
|
|
2668
|
+
nearbyPlayersByUserId(userId) {
|
|
2669
|
+
const areaData = GensokyoMap.getUserCurrentArea(userId);
|
|
2670
|
+
const liveUser = [];
|
|
2671
|
+
Object.keys(GensokyoMap.userCurrentLoal).forEach((_userId) => {
|
|
2672
|
+
const userItem = GensokyoMap.userCurrentLoal[_userId];
|
|
2673
|
+
if (userItem.areaName == areaData.areaName && userItem.floor == areaData.floor) {
|
|
2674
|
+
if (userId !== userItem.userId) {
|
|
2675
|
+
liveUser.push({ userId: userItem.userId, playName: userItem.playName });
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2572
2678
|
});
|
|
2573
|
-
|
|
2679
|
+
return liveUser;
|
|
2574
2680
|
},
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
userInfo.pp -= value;
|
|
2586
|
-
fn && await fn({
|
|
2587
|
-
currentPP: userInfo.pp
|
|
2681
|
+
/** 区域信息格式化 */
|
|
2682
|
+
userAreaTextFormat(gameName, data) {
|
|
2683
|
+
const liveUser = [];
|
|
2684
|
+
Object.keys(GensokyoMap.userCurrentLoal).forEach((userId) => {
|
|
2685
|
+
const areaItem = GensokyoMap.userCurrentLoal[userId];
|
|
2686
|
+
if (areaItem.areaName == data.map.areaName && areaItem.floor == data.map.floor) {
|
|
2687
|
+
if (gameName !== areaItem.playName) {
|
|
2688
|
+
liveUser.push(areaItem.playName);
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2588
2691
|
});
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2692
|
+
const str = `${gameName}[萌新] 当前位置:
|
|
2693
|
+
`;
|
|
2694
|
+
const mapInfo = `区域:【${data.map.areaName}】
|
|
2695
|
+
` + (data.map.info ? data.map.info + "\n\n" : "\n") + (data.map.top ? `上:【${data.map.top}】
|
|
2696
|
+
` : "") + (data.map.down ? `下:【${data.map.down}】
|
|
2697
|
+
` : "") + (data.map.left ? `左:【${data.map.left}】
|
|
2698
|
+
` : "") + (data.map.right ? `右:【${data.map.right}】
|
|
2699
|
+
` : "") + (data.map.type == "传送门" /* 传送门 */ ? `
|
|
2700
|
+
[!]传送门区域` : "") + (data.map.shopName ? `
|
|
2701
|
+
[!]存在商店:${data.map.shopName}` : "") + (data.map.npc ? `
|
|
2702
|
+
[!]存在npc:${data.map.npc.join("、")}` : "") + (data.map.monster ? `
|
|
2703
|
+
[!]存在野怪:${data.map.monster.map((i) => `lv.${i.lv} ${i.name}`).join("、")}` : "") + (liveUser.length ? `
|
|
2704
|
+
[!]区域玩家:${liveUser.length > 3 ? liveUser.slice(0, 3).join("、") + `...等${liveUser.length}` : liveUser.join("、")}` : "");
|
|
2705
|
+
return str + mapInfo;
|
|
2706
|
+
}
|
|
2707
|
+
};
|
|
2708
|
+
|
|
2709
|
+
// src/mapHtml.ts
|
|
2710
|
+
function generateMapHTML(mapData, currentAreaName) {
|
|
2711
|
+
const centerKey = Object.keys(mapData).find((key) => mapData[key].type === "传送门");
|
|
2712
|
+
if (!centerKey) {
|
|
2713
|
+
return "<div>未找到传送门区域</div>";
|
|
2714
|
+
}
|
|
2715
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2716
|
+
const grid = {};
|
|
2717
|
+
let minRow = 0, maxRow = 0, minCol = 0, maxCol = 0;
|
|
2718
|
+
function placeArea(key, row, col) {
|
|
2719
|
+
if (visited.has(key)) return;
|
|
2720
|
+
visited.add(key);
|
|
2721
|
+
const area = mapData[key];
|
|
2722
|
+
if (!area) return;
|
|
2723
|
+
const connections = {
|
|
2724
|
+
top: false,
|
|
2725
|
+
left: false,
|
|
2726
|
+
right: false,
|
|
2727
|
+
down: false
|
|
2728
|
+
};
|
|
2729
|
+
if (!grid[row]) grid[row] = {};
|
|
2730
|
+
grid[row][col] = { area, key, row, col, connections };
|
|
2731
|
+
minRow = Math.min(minRow, row);
|
|
2732
|
+
maxRow = Math.max(maxRow, row);
|
|
2733
|
+
minCol = Math.min(minCol, col);
|
|
2734
|
+
maxCol = Math.max(maxCol, col);
|
|
2735
|
+
if (area.top) {
|
|
2736
|
+
placeArea(area.top, row - 1, col);
|
|
2737
|
+
connections.top = true;
|
|
2738
|
+
if (grid[row - 1]?.[col]) {
|
|
2739
|
+
grid[row - 1][col].connections.down = true;
|
|
2740
|
+
}
|
|
2598
2741
|
}
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
|
|
2605
|
-
if (currentM.value - val < 0) {
|
|
2606
|
-
fn && await fn({
|
|
2607
|
-
val: Math.abs(val),
|
|
2608
|
-
currentVal: currentM.value,
|
|
2609
|
-
err: "余额不足!"
|
|
2610
|
-
});
|
|
2611
|
-
return;
|
|
2742
|
+
if (area.left) {
|
|
2743
|
+
placeArea(area.left, row, col - 1);
|
|
2744
|
+
connections.left = true;
|
|
2745
|
+
if (grid[row]?.[col - 1]) {
|
|
2746
|
+
grid[row][col - 1].connections.right = true;
|
|
2612
2747
|
}
|
|
2613
|
-
await User.ctx.monetary.cost(bindData.aid, val);
|
|
2614
|
-
fn && await fn({
|
|
2615
|
-
val: Math.abs(val),
|
|
2616
|
-
currentVal: currentM.value - val
|
|
2617
|
-
});
|
|
2618
2748
|
}
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
const upProps = [];
|
|
2625
|
-
for (const item of props) {
|
|
2626
|
-
const propsItem = propsData[item.name];
|
|
2627
|
-
if (!propsData[item.name]) continue;
|
|
2628
|
-
if (!userProps[item.name]) {
|
|
2629
|
-
userProps[item.name] = {
|
|
2630
|
-
name: propsItem.name,
|
|
2631
|
-
type: propsItem.type,
|
|
2632
|
-
value: 0
|
|
2633
|
-
};
|
|
2749
|
+
if (area.right) {
|
|
2750
|
+
placeArea(area.right, row, col + 1);
|
|
2751
|
+
connections.right = true;
|
|
2752
|
+
if (grid[row]?.[col + 1]) {
|
|
2753
|
+
grid[row][col + 1].connections.left = true;
|
|
2634
2754
|
}
|
|
2635
|
-
userProps[item.name].value += item.val || 1;
|
|
2636
|
-
upProps.push({ name: item.name, val: userProps[item.name].value });
|
|
2637
2755
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
async loseProps(userId, props, fn) {
|
|
2645
|
-
const userProps = Props.userPorpsTemp[userId];
|
|
2646
|
-
const propsItem = propsData[props.name];
|
|
2647
|
-
if (!userProps) return;
|
|
2648
|
-
if (!propsItem) {
|
|
2649
|
-
fn && await fn({
|
|
2650
|
-
currentProps: { name: props.name, val: 0 },
|
|
2651
|
-
err: "该道具信息不存在!"
|
|
2652
|
-
});
|
|
2653
|
-
return;
|
|
2756
|
+
if (area.down) {
|
|
2757
|
+
placeArea(area.down, row + 1, col);
|
|
2758
|
+
connections.down = true;
|
|
2759
|
+
if (grid[row + 1]?.[col]) {
|
|
2760
|
+
grid[row + 1][col].connections.top = true;
|
|
2761
|
+
}
|
|
2654
2762
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2763
|
+
}
|
|
2764
|
+
__name(placeArea, "placeArea");
|
|
2765
|
+
placeArea(centerKey, 0, 0);
|
|
2766
|
+
const cellWidth = 160;
|
|
2767
|
+
const cellHeight = 120;
|
|
2768
|
+
const svgWidth = (maxCol - minCol + 1) * cellWidth;
|
|
2769
|
+
const svgHeight = (maxRow - minRow + 1) * cellHeight;
|
|
2770
|
+
let html = `
|
|
2771
|
+
<style>
|
|
2772
|
+
.map-container {
|
|
2773
|
+
display: inline-block;
|
|
2774
|
+
position: relative;
|
|
2775
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
2776
|
+
font-size: 12px;
|
|
2777
|
+
background-color: transparent;
|
|
2778
|
+
padding: 20px;
|
|
2779
|
+
border-radius: 12px;
|
|
2780
|
+
min-width: 100vw;
|
|
2781
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
2782
|
+
}
|
|
2783
|
+
.map-table {
|
|
2784
|
+
border-collapse: separate;
|
|
2785
|
+
border-spacing: 0;
|
|
2786
|
+
position: relative;
|
|
2787
|
+
z-index: 2;
|
|
2788
|
+
}
|
|
2789
|
+
.map-cell {
|
|
2790
|
+
width: ${cellWidth}px;
|
|
2791
|
+
height: ${cellHeight}px;
|
|
2792
|
+
border: none;
|
|
2793
|
+
padding: 12px;
|
|
2794
|
+
vertical-align: top;
|
|
2795
|
+
text-align: center;
|
|
2796
|
+
background: rgba(255, 255, 255, 0.95);
|
|
2797
|
+
border-radius: 8px;
|
|
2798
|
+
transition: all 0.3s ease;
|
|
2799
|
+
position: relative;
|
|
2800
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
2801
|
+
backdrop-filter: blur(10px);
|
|
2802
|
+
}
|
|
2803
|
+
.map-cell:hover {
|
|
2804
|
+
transform: translateY(-2px);
|
|
2805
|
+
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
|
|
2806
|
+
}
|
|
2807
|
+
.empty-cell {
|
|
2808
|
+
background: transparent !important;
|
|
2809
|
+
box-shadow: none !important;
|
|
2810
|
+
border: none !important;
|
|
2811
|
+
}
|
|
2812
|
+
.area-name {
|
|
2813
|
+
font-weight: 700;
|
|
2814
|
+
margin-bottom: 6px;
|
|
2815
|
+
color: #2d3748;
|
|
2816
|
+
font-size: 14px;
|
|
2817
|
+
letter-spacing: 0.5px;
|
|
2818
|
+
}
|
|
2819
|
+
.area-type {
|
|
2820
|
+
font-size: 11px;
|
|
2821
|
+
color: #718096;
|
|
2822
|
+
margin-bottom: 6px;
|
|
2823
|
+
padding: 2px 8px;
|
|
2824
|
+
background: rgba(237, 242, 247, 0.8);
|
|
2825
|
+
border-radius: 12px;
|
|
2826
|
+
display: inline-block;
|
|
2827
|
+
}
|
|
2828
|
+
.area-info {
|
|
2829
|
+
font-size: 10px;
|
|
2830
|
+
color: #4a5568;
|
|
2831
|
+
margin-bottom: 6px;
|
|
2832
|
+
font-style: italic;
|
|
2833
|
+
}
|
|
2834
|
+
.monster-list, .npc-list {
|
|
2835
|
+
font-size: 10px;
|
|
2836
|
+
color: #2d3748;
|
|
2837
|
+
text-align: left;
|
|
2838
|
+
margin-top: 6px;
|
|
2839
|
+
padding-left: 8px;
|
|
2840
|
+
}
|
|
2841
|
+
.monster-list {
|
|
2842
|
+
border-left: 2px solid #e53e3e;
|
|
2843
|
+
}
|
|
2844
|
+
.npc-list {
|
|
2845
|
+
border-left: 2px solid #38a169;
|
|
2846
|
+
}
|
|
2847
|
+
.safe {
|
|
2848
|
+
background: linear-gradient(135deg, rgba(224, 247, 250, 0.95), rgba(129, 230, 217, 0.95));
|
|
2849
|
+
border: 2px solid #38b2ac;
|
|
2850
|
+
}
|
|
2851
|
+
.boss {
|
|
2852
|
+
background: linear-gradient(135deg, rgba(255, 235, 238, 0.95), rgba(254, 178, 178, 0.95));
|
|
2853
|
+
border: 2px solid #e53e3e;
|
|
2854
|
+
}
|
|
2855
|
+
.adventure {
|
|
2856
|
+
background: linear-gradient(135deg, rgba(241, 248, 233, 0.95), rgba(154, 230, 180, 0.95));
|
|
2857
|
+
border: 2px solid #38a169;
|
|
2858
|
+
}
|
|
2859
|
+
.portal {
|
|
2860
|
+
background: linear-gradient(135deg, rgba(255, 243, 224, 0.95), rgba(251, 211, 141, 0.95));
|
|
2861
|
+
border: 2px solid #ed8936;
|
|
2862
|
+
}
|
|
2863
|
+
.current {
|
|
2864
|
+
background: linear-gradient(135deg, rgba(255, 249, 196, 0.95), rgba(254, 240, 138, 0.95)) !important;
|
|
2865
|
+
border: 3px solid #d69e2e !important;
|
|
2866
|
+
box-shadow: 0 0 20px rgba(214, 158, 46, 0.4), 0 8px 16px rgba(0, 0, 0, 0.2);
|
|
2867
|
+
transform: scale(1.08);
|
|
2868
|
+
z-index: 10;
|
|
2869
|
+
animation: glow 2s ease-in-out infinite alternate;
|
|
2870
|
+
}
|
|
2871
|
+
@keyframes glow {
|
|
2872
|
+
from {
|
|
2873
|
+
box-shadow: 0 0 20px rgba(214, 158, 46, 0.4), 0 8px 16px rgba(0, 0, 0, 0.2);
|
|
2661
2874
|
}
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2875
|
+
to {
|
|
2876
|
+
box-shadow: 0 0 30px rgba(214, 158, 46, 0.6), 0 10px 20px rgba(0, 0, 0, 0.3);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
.current .area-name {
|
|
2880
|
+
color: #744210;
|
|
2881
|
+
font-weight: 900;
|
|
2882
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
2883
|
+
}
|
|
2884
|
+
.current-marker {
|
|
2885
|
+
display: inline-block;
|
|
2886
|
+
width: 10px;
|
|
2887
|
+
height: 10px;
|
|
2888
|
+
background: linear-gradient(135deg, #d69e2e, #744210);
|
|
2889
|
+
border-radius: 50%;
|
|
2890
|
+
margin-right: 6px;
|
|
2891
|
+
animation: pulse 1.5s ease-in-out infinite;
|
|
2892
|
+
box-shadow: 0 0 8px rgba(214, 158, 46, 0.8);
|
|
2893
|
+
}
|
|
2894
|
+
@keyframes pulse {
|
|
2895
|
+
0% { transform: scale(1); opacity: 1; }
|
|
2896
|
+
50% { transform: scale(1.4); opacity: 0.8; }
|
|
2897
|
+
100% { transform: scale(1); opacity: 1; }
|
|
2898
|
+
}
|
|
2899
|
+
.connection-lines {
|
|
2900
|
+
position: absolute;
|
|
2901
|
+
top: 0;
|
|
2902
|
+
left: 0;
|
|
2903
|
+
width: 100%;
|
|
2904
|
+
height: 100%;
|
|
2905
|
+
z-index: 1;
|
|
2906
|
+
pointer-events: none;
|
|
2907
|
+
}
|
|
2908
|
+
.connection-line {
|
|
2909
|
+
stroke: rgba(255, 255, 255, 0.7);
|
|
2910
|
+
stroke-width: 3;
|
|
2911
|
+
stroke-linecap: round;
|
|
2912
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
|
2913
|
+
}
|
|
2914
|
+
.connection-line-dotted {
|
|
2915
|
+
stroke-dasharray: 5, 5;
|
|
2916
|
+
}
|
|
2917
|
+
.connection-line-solid {
|
|
2918
|
+
stroke-dasharray: none;
|
|
2919
|
+
}
|
|
2920
|
+
.connection-dot {
|
|
2921
|
+
fill: rgba(255, 255, 255, 0.9);
|
|
2922
|
+
stroke: #4a5568;
|
|
2923
|
+
stroke-width: 1;
|
|
2924
|
+
filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.2));
|
|
2925
|
+
}
|
|
2926
|
+
</style>
|
|
2927
|
+
<div class="map-container">
|
|
2928
|
+
<svg class="connection-lines" width="${svgWidth}" height="${svgHeight}">
|
|
2929
|
+
`;
|
|
2930
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
2931
|
+
for (let c = minCol; c <= maxCol; c++) {
|
|
2932
|
+
const cell = grid[r]?.[c];
|
|
2933
|
+
if (cell) {
|
|
2934
|
+
const { connections } = cell;
|
|
2935
|
+
const x = (c - minCol) * cellWidth + cellWidth / 2;
|
|
2936
|
+
const y = (r - minRow) * cellHeight + cellHeight / 2;
|
|
2937
|
+
html += `<circle class="connection-dot" cx="${x}" cy="${y}" r="4" />`;
|
|
2938
|
+
if (connections.top) {
|
|
2939
|
+
const targetX = x;
|
|
2940
|
+
const targetY = y - cellHeight;
|
|
2941
|
+
html += `<line class="connection-line connection-line-dotted"
|
|
2942
|
+
x1="${x}" y1="${y}"
|
|
2943
|
+
x2="${targetX}" y2="${targetY}" />`;
|
|
2944
|
+
}
|
|
2945
|
+
if (connections.down) {
|
|
2946
|
+
const targetX = x;
|
|
2947
|
+
const targetY = y + cellHeight;
|
|
2948
|
+
html += `<line class="connection-line connection-line-dotted"
|
|
2949
|
+
x1="${x}" y1="${y}"
|
|
2950
|
+
x2="${targetX}" y2="${targetY}" />`;
|
|
2951
|
+
}
|
|
2952
|
+
if (connections.left) {
|
|
2953
|
+
const targetX = x - cellWidth;
|
|
2954
|
+
const targetY = y;
|
|
2955
|
+
html += `<line class="connection-line connection-line-dotted"
|
|
2956
|
+
x1="${x}" y1="${y}"
|
|
2957
|
+
x2="${targetX}" y2="${targetY}" />`;
|
|
2958
|
+
}
|
|
2959
|
+
if (connections.right) {
|
|
2960
|
+
const targetX = x + cellWidth;
|
|
2961
|
+
const targetY = y;
|
|
2962
|
+
html += `<line class="connection-line connection-line-dotted"
|
|
2963
|
+
x1="${x}" y1="${y}"
|
|
2964
|
+
x2="${targetX}" y2="${targetY}" />`;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2668
2967
|
}
|
|
2669
|
-
userProps[props.name].value -= props.val || 1;
|
|
2670
|
-
if (userProps[props.name].value == 0) delete userProps[props.name];
|
|
2671
|
-
await Props.setDatabasePropsData(userId);
|
|
2672
|
-
fn && await fn({
|
|
2673
|
-
currentProps: { name: props.name, val: userProps[props.name]?.value || 0 }
|
|
2674
|
-
});
|
|
2675
|
-
},
|
|
2676
|
-
/** 目标是否死亡 */
|
|
2677
|
-
isDie(userId) {
|
|
2678
|
-
return User.userTempData[userId]?.isDie;
|
|
2679
2968
|
}
|
|
2680
|
-
|
|
2969
|
+
html += `</svg><table class="map-table">`;
|
|
2970
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
2971
|
+
html += "<tr>";
|
|
2972
|
+
for (let c = minCol; c <= maxCol; c++) {
|
|
2973
|
+
const cell = grid[r]?.[c];
|
|
2974
|
+
if (cell) {
|
|
2975
|
+
const { area, key } = cell;
|
|
2976
|
+
const isCurrent = currentAreaName === area.areaName;
|
|
2977
|
+
const typeClass = area.type === "安全区" ? "safe" : area.type === "BOSS区" ? "boss" : area.type === "冒险区" ? "adventure" : area.type === "传送门" ? "portal" : "";
|
|
2978
|
+
const currentClass = isCurrent ? "current" : "";
|
|
2979
|
+
html += `<td class="map-cell ${typeClass} ${currentClass}">`;
|
|
2980
|
+
html += `<div class="area-name">`;
|
|
2981
|
+
if (isCurrent) {
|
|
2982
|
+
html += `<span class="current-marker"></span>`;
|
|
2983
|
+
}
|
|
2984
|
+
html += `${area.areaName}`;
|
|
2985
|
+
if (isCurrent) {
|
|
2986
|
+
html += ` <span style="color:#744210;font-size:11px;font-weight:600;">(当前位置)</span>`;
|
|
2987
|
+
}
|
|
2988
|
+
html += `</div>`;
|
|
2989
|
+
html += `<div class="area-type">${area.type} (Lv.${area.needLv}+)</div>`;
|
|
2990
|
+
if (area.info) {
|
|
2991
|
+
html += `<div class="area-info">${area.info}</div>`;
|
|
2992
|
+
}
|
|
2993
|
+
if (area.npc && area.npc.length > 0) {
|
|
2994
|
+
html += `<div class="npc-list">NPC: ${area.npc.join(", ")}</div>`;
|
|
2995
|
+
}
|
|
2996
|
+
if (area.monster && area.monster.length > 0) {
|
|
2997
|
+
html += `<div class="monster-list">`;
|
|
2998
|
+
area.monster.forEach((m) => {
|
|
2999
|
+
html += `<div style="margin: 2px 0;">${m.name} <span style="color:#e53e3e">Lv.${m.lv}</span></div>`;
|
|
3000
|
+
});
|
|
3001
|
+
html += `</div>`;
|
|
3002
|
+
}
|
|
3003
|
+
html += `</td>`;
|
|
3004
|
+
} else {
|
|
3005
|
+
html += `<td class="map-cell empty-cell"></td>`;
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
html += "</tr>";
|
|
3009
|
+
}
|
|
3010
|
+
html += `
|
|
3011
|
+
</table>
|
|
3012
|
+
</div>
|
|
3013
|
+
`;
|
|
3014
|
+
return html;
|
|
3015
|
+
}
|
|
3016
|
+
__name(generateMapHTML, "generateMapHTML");
|
|
2681
3017
|
|
|
2682
3018
|
// src/index.ts
|
|
2683
3019
|
var name = "smmcat-gensokyo";
|
|
2684
3020
|
var inject = {
|
|
2685
|
-
required: ["monetary", "database"]
|
|
3021
|
+
required: ["monetary", "database", "puppeteer"]
|
|
2686
3022
|
};
|
|
2687
3023
|
var Config = import_koishi2.Schema.object({});
|
|
2688
3024
|
function apply(ctx, config) {
|
|
@@ -2709,17 +3045,6 @@ function apply(ctx, config) {
|
|
|
2709
3045
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
2710
3046
|
}
|
|
2711
3047
|
GensokyoMap.move(session, "top" /* 上 */, async (val) => {
|
|
2712
|
-
if (BattleData.isTeam(session)) {
|
|
2713
|
-
const { userId } = session;
|
|
2714
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
2715
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
2716
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
2717
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
2718
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
2719
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
2720
|
-
}
|
|
2721
|
-
});
|
|
2722
|
-
}
|
|
2723
3048
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
2724
3049
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
2725
3050
|
if (random(0, 10) <= 2) {
|
|
@@ -2746,17 +3071,6 @@ function apply(ctx, config) {
|
|
|
2746
3071
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
2747
3072
|
}
|
|
2748
3073
|
GensokyoMap.move(session, "down" /* 下 */, async (val) => {
|
|
2749
|
-
if (BattleData.isTeam(session)) {
|
|
2750
|
-
const { userId } = session;
|
|
2751
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
2752
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
2753
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
2754
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
2755
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
2756
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
2757
|
-
}
|
|
2758
|
-
});
|
|
2759
|
-
}
|
|
2760
3074
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
2761
3075
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
2762
3076
|
if (random(0, 10) <= 2) {
|
|
@@ -2783,17 +3097,6 @@ function apply(ctx, config) {
|
|
|
2783
3097
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
2784
3098
|
}
|
|
2785
3099
|
GensokyoMap.move(session, "left" /* 左 */, async (val) => {
|
|
2786
|
-
if (BattleData.isTeam(session)) {
|
|
2787
|
-
const { userId } = session;
|
|
2788
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
2789
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
2790
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
2791
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
2792
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
2793
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
2794
|
-
}
|
|
2795
|
-
});
|
|
2796
|
-
}
|
|
2797
3100
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
2798
3101
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
2799
3102
|
if (random(0, 10) <= 2) {
|
|
@@ -2820,17 +3123,6 @@ function apply(ctx, config) {
|
|
|
2820
3123
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
2821
3124
|
}
|
|
2822
3125
|
GensokyoMap.move(session, "right" /* 右 */, async (val) => {
|
|
2823
|
-
if (BattleData.isTeam(session)) {
|
|
2824
|
-
const { userId } = session;
|
|
2825
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
2826
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
2827
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
2828
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
2829
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
2830
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
2831
|
-
}
|
|
2832
|
-
});
|
|
2833
|
-
}
|
|
2834
3126
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
2835
3127
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
2836
3128
|
if (random(0, 10) <= 2) {
|
|
@@ -2962,12 +3254,16 @@ function apply(ctx, config) {
|
|
|
2962
3254
|
const userData = await User.getUserAttribute(session);
|
|
2963
3255
|
if (!userData) return;
|
|
2964
3256
|
GensokyoMap.initUserPoistion(session, userData);
|
|
3257
|
+
if (BattleData.isBattle(session)) {
|
|
3258
|
+
await session.send("当前正在战斗,请结束后再使用改");
|
|
3259
|
+
return;
|
|
3260
|
+
}
|
|
2965
3261
|
if (temp[session.userId] == void 0) {
|
|
2966
3262
|
temp[session.userId] = 0;
|
|
2967
3263
|
}
|
|
2968
3264
|
const useTime = Date.now() - temp[session.userId];
|
|
2969
3265
|
if (useTime < 36e4) {
|
|
2970
|
-
return `请等待下一个补给时间!剩余${Math.floor(36e4 - useTime / 6e4)}分钟。`;
|
|
3266
|
+
return `请等待下一个补给时间!剩余${Math.floor((36e4 - useTime) / 6e4)}分钟。`;
|
|
2971
3267
|
}
|
|
2972
3268
|
temp[session.userId] = Date.now();
|
|
2973
3269
|
const { maxHp, maxMp, playName } = User.getUserAttributeByUserId(session.userId);
|
|
@@ -2981,18 +3277,27 @@ function apply(ctx, config) {
|
|
|
2981
3277
|
});
|
|
2982
3278
|
ctx.command("幻想乡/队伍操作");
|
|
2983
3279
|
ctx.command("队伍操作/队伍创建").action(async ({ session }) => {
|
|
3280
|
+
const userData = await User.getUserAttribute(session);
|
|
3281
|
+
if (!userData) return;
|
|
3282
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2984
3283
|
if (BattleData.isBattle(session)) {
|
|
2985
3284
|
return `战斗中无法进行队伍创建操作!`;
|
|
2986
3285
|
}
|
|
2987
3286
|
await BattleData.creatTeam(session);
|
|
2988
3287
|
});
|
|
2989
3288
|
ctx.command("队伍操作/队伍信息").action(async ({ session }) => {
|
|
3289
|
+
const userData = await User.getUserAttribute(session);
|
|
3290
|
+
if (!userData) return;
|
|
3291
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2990
3292
|
const team = BattleData.teamListByUser(session.userId);
|
|
2991
3293
|
if (!team.length) return `你还没有队伍...`;
|
|
2992
3294
|
return `当前队伍信息如下:
|
|
2993
3295
|
` + team.map((item) => `lv.${item.lv} ${item.playName} [${BattleData.teamTemp[item.userId].identity}]`).join("\n");
|
|
2994
3296
|
});
|
|
2995
3297
|
ctx.command("队伍操作/队伍邀请 <playName>").action(async ({ session }, playName) => {
|
|
3298
|
+
const userData = await User.getUserAttribute(session);
|
|
3299
|
+
if (!userData) return;
|
|
3300
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2996
3301
|
if (BattleData.isBattle(session)) {
|
|
2997
3302
|
return `战斗中无法进行队伍邀请操作!`;
|
|
2998
3303
|
}
|
|
@@ -3002,23 +3307,42 @@ function apply(ctx, config) {
|
|
|
3002
3307
|
await BattleData.invitationTeam(session, playName);
|
|
3003
3308
|
});
|
|
3004
3309
|
ctx.command("队伍操作/队伍加入").action(async ({ session }) => {
|
|
3310
|
+
const userData = await User.getUserAttribute(session);
|
|
3311
|
+
if (!userData) return;
|
|
3312
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
3005
3313
|
if (BattleData.isBattle(session)) {
|
|
3006
3314
|
return `战斗中无法进行队伍创建操作!`;
|
|
3007
3315
|
}
|
|
3008
3316
|
await BattleData.joinTeam(session);
|
|
3009
3317
|
});
|
|
3010
3318
|
ctx.command("队伍操作/队伍退出").action(async ({ session }) => {
|
|
3319
|
+
const userData = await User.getUserAttribute(session);
|
|
3320
|
+
if (!userData) return;
|
|
3321
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
3011
3322
|
if (BattleData.isBattle(session)) {
|
|
3012
3323
|
return `战斗中无法进行队伍退出操作!`;
|
|
3013
3324
|
}
|
|
3014
3325
|
await BattleData.exitTeam(session);
|
|
3015
3326
|
});
|
|
3016
3327
|
ctx.command("队伍操作/队伍解散").action(async ({ session }) => {
|
|
3328
|
+
const userData = await User.getUserAttribute(session);
|
|
3329
|
+
if (!userData) return;
|
|
3330
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
3017
3331
|
if (BattleData.isBattle(session)) {
|
|
3018
3332
|
return `战斗中无法进行队伍解散操作!`;
|
|
3019
3333
|
}
|
|
3020
3334
|
await BattleData.dissolveTeam(session);
|
|
3021
3335
|
});
|
|
3336
|
+
ctx.command("幻想乡/地图").action(async ({ session }) => {
|
|
3337
|
+
const userData = await User.getUserAttribute(session);
|
|
3338
|
+
if (!userData) return;
|
|
3339
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
3340
|
+
const { areaName, floor } = GensokyoMap.userCurrentLoal[session.userId];
|
|
3341
|
+
const mapLocal = GensokyoMap.mapLocalData[floor];
|
|
3342
|
+
const html = generateMapHTML(mapLocal, areaName);
|
|
3343
|
+
console.log(html);
|
|
3344
|
+
await session.send(await ctx.puppeteer.render(html));
|
|
3345
|
+
});
|
|
3022
3346
|
}
|
|
3023
3347
|
__name(apply, "apply");
|
|
3024
3348
|
// Annotate the CommonJS export names for ESM import in node:
|