koishi-plugin-smmcat-gensokyo 0.0.29 → 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 +1243 -1256
- 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: {
|
|
@@ -1835,847 +1412,1297 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
|
1835
1412
|
}
|
|
1836
1413
|
}
|
|
1837
1414
|
}
|
|
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);
|
|
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);
|
|
1423
|
+
}
|
|
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
|
+
}
|
|
1506
|
+
}
|
|
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;
|
|
1521
|
+
}
|
|
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: {}
|
|
1565
|
+
};
|
|
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: {}
|
|
1604
|
+
};
|
|
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;
|
|
1622
|
+
}
|
|
1623
|
+
const msg = `回复成功,玩家当前血量:${val.currentHP}`;
|
|
1624
|
+
await session.send(msg);
|
|
1625
|
+
});
|
|
1626
|
+
}, "fn")
|
|
1627
|
+
},
|
|
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;
|
|
1638
|
+
}
|
|
1639
|
+
const msg = `回复成功,玩家当前蓝量:${val.currentMP}`;
|
|
1640
|
+
await session.send(msg);
|
|
1641
|
+
});
|
|
1642
|
+
}, "fn")
|
|
1643
|
+
},
|
|
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);
|
|
1657
|
+
});
|
|
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 };
|
|
1670
|
+
}
|
|
1671
|
+
if (!User.isDie(session.userId)) {
|
|
1672
|
+
session.send(`您还没有阵亡,使用失败!`);
|
|
1673
|
+
return { err: true };
|
|
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
|
+
});
|
|
1698
|
+
const temp = {};
|
|
1699
|
+
const propsList = await ctx.database.get("smm_gensokyo_user_props", {});
|
|
1700
|
+
propsList.forEach((item) => {
|
|
1701
|
+
temp[item.userId] = item.props;
|
|
1702
|
+
});
|
|
1703
|
+
Props.userPorpsTemp = temp;
|
|
1704
|
+
},
|
|
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);
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
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);
|
|
1846
1735
|
}
|
|
1847
1736
|
},
|
|
1848
|
-
/**
|
|
1849
|
-
async
|
|
1850
|
-
const
|
|
1851
|
-
const
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
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
|
-
__name(initBattleAttribute, "initBattleAttribute");
|
|
2032
|
-
|
|
2033
|
-
// src/data/initProps.ts
|
|
2034
|
-
var propsData = {
|
|
2035
|
-
"红药": {
|
|
2036
|
-
name: "红药",
|
|
2037
|
-
type: "消耗类" /* 消耗类 */,
|
|
2038
|
-
info: "回复自身20HP",
|
|
2039
|
-
price: 10,
|
|
2040
|
-
fn: /* @__PURE__ */ __name(async function(session) {
|
|
2041
|
-
User.giveHPMP(session.userId, { hp: 20 }, async (val) => {
|
|
2042
|
-
if (val.err) {
|
|
2043
|
-
await session.send(val.err);
|
|
2044
|
-
return;
|
|
2045
|
-
}
|
|
2046
|
-
const msg = `回复成功,玩家当前血量:${val.currentHP}`;
|
|
2047
|
-
await session.send(msg);
|
|
2048
|
-
});
|
|
2049
|
-
}, "fn")
|
|
2014
|
+
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
2050
2015
|
},
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
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
|
+
},
|
|
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 });
|
|
2062
|
+
},
|
|
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: "角色已死亡,无法使用恢复道具。"
|
|
2064
2072
|
});
|
|
2065
|
-
|
|
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;
|
|
2084
|
+
}
|
|
2085
|
+
if (agent.mp + (value.mp || 0) < agent.maxMp) {
|
|
2086
|
+
agent.mp += value.mp || 0;
|
|
2087
|
+
} else {
|
|
2088
|
+
agent.mp = agent.maxMp;
|
|
2089
|
+
}
|
|
2090
|
+
fn && await fn({
|
|
2091
|
+
currentHP: agent.hp,
|
|
2092
|
+
currentMP: agent.mp
|
|
2093
|
+
});
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
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
|
|
2134
|
+
});
|
|
2135
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2066
2136
|
},
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
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;
|
|
2146
|
+
}
|
|
2147
|
+
fn && await fn({
|
|
2148
|
+
currentPP: userInfo.pp
|
|
2149
|
+
});
|
|
2150
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2151
|
+
},
|
|
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值不够,消耗失败!"
|
|
2080
2159
|
});
|
|
2081
|
-
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
userInfo.pp -= value;
|
|
2163
|
+
fn && await fn({
|
|
2164
|
+
currentPP: userInfo.pp
|
|
2165
|
+
});
|
|
2166
|
+
await User.setDatabaseUserAttribute(userId);
|
|
2082
2167
|
},
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
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 });
|
|
2175
|
+
}
|
|
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;
|
|
2093
2189
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2190
|
+
await User.ctx.monetary.cost(bindData.aid, val);
|
|
2191
|
+
fn && await fn({
|
|
2192
|
+
val: Math.abs(val),
|
|
2193
|
+
currentVal: currentM.value - val
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
},
|
|
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
|
+
};
|
|
2097
2211
|
}
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2212
|
+
userProps[item.name].value += item.val || 1;
|
|
2213
|
+
upProps.push({ name: item.name, val: userProps[item.name].value });
|
|
2214
|
+
}
|
|
2215
|
+
await Props.setDatabasePropsData(userId);
|
|
2216
|
+
fn && await fn({
|
|
2217
|
+
currentProps: upProps
|
|
2218
|
+
});
|
|
2219
|
+
},
|
|
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: "该道具信息不存在!"
|
|
2101
2229
|
});
|
|
2102
|
-
|
|
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;
|
|
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;
|
|
2103
2256
|
}
|
|
2104
2257
|
};
|
|
2105
2258
|
|
|
2106
|
-
// src/
|
|
2107
|
-
var
|
|
2259
|
+
// src/map.ts
|
|
2260
|
+
var delay = /* @__PURE__ */ __name((ms) => new Promise((resolve) => setTimeout(resolve, ms)), "delay");
|
|
2261
|
+
var GensokyoMap = {
|
|
2108
2262
|
config: {},
|
|
2109
2263
|
ctx: {},
|
|
2110
|
-
|
|
2264
|
+
mapLocalData: {},
|
|
2265
|
+
userCurrentLoal: {},
|
|
2111
2266
|
async init(config, ctx) {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
ctx.database.extend("
|
|
2267
|
+
GensokyoMap.config = config;
|
|
2268
|
+
GensokyoMap.ctx = ctx;
|
|
2269
|
+
ctx.database.extend("smm_gensokyo_map_position", {
|
|
2115
2270
|
userId: "string",
|
|
2116
|
-
|
|
2271
|
+
floor: "integer",
|
|
2272
|
+
areaName: "string",
|
|
2273
|
+
moveing: "boolean",
|
|
2274
|
+
playName: "string"
|
|
2117
2275
|
}, {
|
|
2118
2276
|
primary: "userId",
|
|
2119
2277
|
autoInc: false
|
|
2120
2278
|
});
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
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 }]
|
|
2192
2465
|
}
|
|
2193
|
-
}
|
|
2194
|
-
});
|
|
2195
|
-
}
|
|
2196
|
-
};
|
|
2197
|
-
var coolingTemp = {};
|
|
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
|
|
2224
|
-
}
|
|
2225
|
-
},
|
|
2226
|
-
["法师" /* 法师 */]: {
|
|
2227
|
-
info: "精通元素魔法,能够打出爆发伤害",
|
|
2228
|
-
initStatus: {
|
|
2229
|
-
userId: "",
|
|
2230
|
-
playName: "",
|
|
2231
|
-
type: "法师" /* 法师 */,
|
|
2232
|
-
exp: 0,
|
|
2233
|
-
maxExp: 100,
|
|
2234
|
-
lv: 1,
|
|
2235
|
-
hp: 100,
|
|
2236
|
-
maxHp: 100,
|
|
2237
|
-
mp: 100,
|
|
2238
|
-
maxMp: 100,
|
|
2239
|
-
pp: 100,
|
|
2240
|
-
maxPp: 100,
|
|
2241
|
-
atk: 10,
|
|
2242
|
-
def: 2,
|
|
2243
|
-
chr: 50,
|
|
2244
|
-
csr: 0,
|
|
2245
|
-
ghd: 1.2,
|
|
2246
|
-
speed: 5,
|
|
2247
|
-
evasion: 100,
|
|
2248
|
-
hit: 100
|
|
2249
|
-
}
|
|
2250
|
-
},
|
|
2251
|
-
["刺客" /* 刺客 */]: {
|
|
2252
|
-
info: "迅捷攻击,高闪避值的高敏玩家",
|
|
2253
|
-
initStatus: {
|
|
2254
|
-
userId: "",
|
|
2255
|
-
playName: "",
|
|
2256
|
-
type: "刺客" /* 刺客 */,
|
|
2257
|
-
exp: 0,
|
|
2258
|
-
maxExp: 100,
|
|
2259
|
-
lv: 1,
|
|
2260
|
-
hp: 90,
|
|
2261
|
-
maxHp: 90,
|
|
2262
|
-
mp: 70,
|
|
2263
|
-
maxMp: 70,
|
|
2264
|
-
pp: 100,
|
|
2265
|
-
maxPp: 100,
|
|
2266
|
-
atk: 8,
|
|
2267
|
-
def: 2,
|
|
2268
|
-
chr: 80,
|
|
2269
|
-
csr: 0,
|
|
2270
|
-
ghd: 1.3,
|
|
2271
|
-
speed: 6,
|
|
2272
|
-
evasion: 120,
|
|
2273
|
-
hit: 100
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2276
|
-
};
|
|
2277
|
-
var User = {
|
|
2278
|
-
config: {},
|
|
2279
|
-
ctx: {},
|
|
2280
|
-
userTempData: {},
|
|
2281
|
-
async init(config, ctx) {
|
|
2282
|
-
User.config = config;
|
|
2283
|
-
User.ctx = ctx;
|
|
2284
|
-
ctx.model.extend(
|
|
2285
|
-
"smm_gensokyo_user_attribute",
|
|
2286
|
-
{
|
|
2287
|
-
userId: "string",
|
|
2288
|
-
playName: "string",
|
|
2289
|
-
type: "string",
|
|
2290
|
-
exp: "integer",
|
|
2291
|
-
lv: "integer",
|
|
2292
|
-
hp: "integer",
|
|
2293
|
-
mp: "integer",
|
|
2294
|
-
pp: "integer",
|
|
2295
|
-
isDie: "boolean"
|
|
2296
2466
|
},
|
|
2297
|
-
{
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
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
|
-
|
|
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: "大草场"
|
|
2346
2538
|
}
|
|
2347
2539
|
}
|
|
2348
|
-
});
|
|
2349
|
-
return temp;
|
|
2350
|
-
},
|
|
2351
|
-
/** 通过 userId 获取角色属性 */
|
|
2352
|
-
getUserAttributeByUserId(userId) {
|
|
2353
|
-
return User.getUserAddLvAttribute(userId) || null;
|
|
2354
|
-
},
|
|
2355
|
-
/** 创建游戏账号 */
|
|
2356
|
-
async createPlayUser(session) {
|
|
2357
|
-
const [data] = await User.ctx.database.get("smm_gensokyo_user_attribute", { userId: session.userId });
|
|
2358
|
-
if (data) {
|
|
2359
|
-
await session.send("已存在账号,请勿重复创建!");
|
|
2360
|
-
return;
|
|
2361
|
-
}
|
|
2362
|
-
await session.send("请输入自己的游戏昵称:(60s)");
|
|
2363
|
-
const playname = await session.prompt(6e4);
|
|
2364
|
-
if (playname == void 0) return;
|
|
2365
|
-
const [repeat] = await User.ctx.database.get("smm_gensokyo_user_attribute", { playName: playname.trim() });
|
|
2366
|
-
if (repeat) {
|
|
2367
|
-
await session.send("名字重复,请更换一个名字。");
|
|
2368
|
-
return;
|
|
2369
|
-
}
|
|
2370
|
-
if (Object.keys(monsterData).includes(playname?.trim())) {
|
|
2371
|
-
await session.send("请不要设置怪物的名字!");
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
if (playname.trim().length > 6 || playname.trim().length < 1) {
|
|
2375
|
-
await session.send("名字长度有问题,要求小于 6个字,大于 1个字");
|
|
2376
|
-
return;
|
|
2377
|
-
}
|
|
2378
|
-
await session.send(`请输入要专职的职业:(60s)
|
|
2379
|
-
${Object.keys(UserOccDict).map((i) => `【${i}】:${UserOccDict[i].info}`).join("\n")}`);
|
|
2380
|
-
let jobType = await session.prompt(6e4);
|
|
2381
|
-
if (jobType == void 0) return;
|
|
2382
|
-
while (!Object.keys(UserOccDict).includes(jobType)) {
|
|
2383
|
-
await session.send("未找到该职业,请重新选择!");
|
|
2384
|
-
jobType = await session.prompt(6e4);
|
|
2385
|
-
}
|
|
2386
|
-
const temp = {
|
|
2387
|
-
userId: session.userId,
|
|
2388
|
-
playName: playname.trim(),
|
|
2389
|
-
type: jobType,
|
|
2390
|
-
hp: UserOccDict[jobType].initStatus.hp,
|
|
2391
|
-
pp: UserOccDict[jobType].initStatus.pp,
|
|
2392
|
-
mp: UserOccDict[jobType].initStatus.mp,
|
|
2393
|
-
lv: 1,
|
|
2394
|
-
exp: 0,
|
|
2395
|
-
isDie: false
|
|
2396
|
-
};
|
|
2397
|
-
User.ctx.database.create("smm_gensokyo_user_attribute", temp);
|
|
2398
|
-
User.userTempData[session.userId] = temp;
|
|
2399
|
-
await Props.initUserPropsData(session.userId);
|
|
2400
|
-
await session.send("创建成功!\n" + User.userAttributeTextFormat(session.userId));
|
|
2401
|
-
},
|
|
2402
|
-
/** 信息格式化 */
|
|
2403
|
-
userAttributeTextFormat(userId) {
|
|
2404
|
-
if (!User.userTempData[userId]) {
|
|
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}` : "");
|
|
2424
|
-
},
|
|
2425
|
-
/** 写入用户数据到数据库 */
|
|
2426
|
-
async setDatabaseUserAttribute(userId) {
|
|
2427
|
-
const userInfo = User.userTempData[userId];
|
|
2428
|
-
if (!userInfo) return;
|
|
2429
|
-
const temp = {
|
|
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
2540
|
};
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
const beforData = { ...User.getUserAttributeByUserId(userId) };
|
|
2444
|
-
let isUp = false;
|
|
2445
|
-
userInfo.exp += value;
|
|
2446
|
-
while (true) {
|
|
2447
|
-
const { maxExp } = User.getUserAttributeByUserId(userId);
|
|
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
|
|
2462
|
-
};
|
|
2463
|
-
fn && await fn(upTemp);
|
|
2464
|
-
}
|
|
2465
|
-
await User.setDatabaseUserAttribute(userId);
|
|
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);
|
|
2473
|
-
},
|
|
2474
|
-
/** 给予玩家复活 */
|
|
2475
|
-
async giveLife(userId, val, fn) {
|
|
2476
|
-
const userInfo = User.userTempData[userId];
|
|
2477
|
-
if (!val) {
|
|
2478
|
-
const { maxHp } = User.getUserAttributeByUserId(userId);
|
|
2479
|
-
userInfo.hp = maxHp;
|
|
2480
|
-
} else {
|
|
2481
|
-
userInfo.hp = val;
|
|
2482
|
-
}
|
|
2483
|
-
await User.setDatabaseUserAttribute(userId);
|
|
2484
|
-
fn && await fn({ currentHP: userInfo.hp });
|
|
2485
|
-
},
|
|
2486
|
-
/** 给予玩家血量或者蓝量 */
|
|
2487
|
-
async giveHPMP(userId, value, fn) {
|
|
2488
|
-
const userInfo = User.userTempData[userId];
|
|
2489
|
-
if (!userInfo) return;
|
|
2490
|
-
if (userInfo.isDie) {
|
|
2491
|
-
fn && await fn({
|
|
2492
|
-
currentHP: 0,
|
|
2493
|
-
currentMP: 0,
|
|
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;
|
|
2507
|
-
}
|
|
2508
|
-
if (agent.mp + (value.mp || 0) < agent.maxMp) {
|
|
2509
|
-
agent.mp += value.mp || 0;
|
|
2510
|
-
} else {
|
|
2511
|
-
agent.mp = agent.maxMp;
|
|
2512
|
-
}
|
|
2513
|
-
fn && await fn({
|
|
2514
|
-
currentHP: agent.hp,
|
|
2515
|
-
currentMP: agent.mp
|
|
2516
|
-
});
|
|
2517
|
-
return;
|
|
2518
|
-
}
|
|
2519
|
-
const { maxHp, maxMp } = User.getUserAttributeByUserId(userId);
|
|
2520
|
-
if (value.hp && !value.mp && userInfo.hp == maxHp) {
|
|
2521
|
-
fn && await fn({
|
|
2522
|
-
currentHP: userInfo.hp,
|
|
2523
|
-
currentMP: userInfo.mp,
|
|
2524
|
-
err: "当前血量已满,无需回复。"
|
|
2525
|
-
});
|
|
2526
|
-
return;
|
|
2527
|
-
}
|
|
2528
|
-
if (value.mp && !value.hp && userInfo.mp == maxMp) {
|
|
2529
|
-
fn && await fn({
|
|
2530
|
-
currentHP: userInfo.hp,
|
|
2531
|
-
currentMP: userInfo.mp,
|
|
2532
|
-
err: "当前蓝量已满,无需回复。"
|
|
2533
|
-
});
|
|
2534
|
-
return;
|
|
2535
|
-
}
|
|
2536
|
-
if (value.mp && value.hp && userInfo.mp == maxMp && userInfo.hp == maxHp) {
|
|
2537
|
-
fn && await fn({
|
|
2538
|
-
currentHP: userInfo.hp,
|
|
2539
|
-
currentMP: userInfo.mp,
|
|
2540
|
-
err: "当前状态全满,无需回复。"
|
|
2541
|
-
});
|
|
2542
|
-
return;
|
|
2543
|
-
}
|
|
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
|
-
},
|
|
2560
|
-
/** 给予玩家PP值 */
|
|
2561
|
-
async givePP(userId, value, fn) {
|
|
2562
|
-
const userInfo = User.userTempData[userId];
|
|
2563
|
-
if (!userInfo) return;
|
|
2564
|
-
const { maxPp } = User.getUserAttributeByUserId(userId);
|
|
2565
|
-
if (userInfo.pp + value < maxPp) {
|
|
2566
|
-
userInfo.pp += value;
|
|
2567
|
-
} else {
|
|
2568
|
-
userInfo.pp = maxPp;
|
|
2569
|
-
}
|
|
2570
|
-
fn && await fn({
|
|
2571
|
-
currentPP: userInfo.pp
|
|
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;
|
|
2572
2547
|
});
|
|
2573
|
-
|
|
2548
|
+
GensokyoMap.userCurrentLoal = poistionTemp;
|
|
2574
2549
|
},
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
if (userInfo.pp - value < 0) {
|
|
2579
|
-
fn && await fn({
|
|
2580
|
-
currentPP: userInfo.pp,
|
|
2581
|
-
err: "PP值不够,消耗失败!"
|
|
2582
|
-
});
|
|
2583
|
-
return;
|
|
2584
|
-
}
|
|
2585
|
-
userInfo.pp -= value;
|
|
2586
|
-
fn && await fn({
|
|
2587
|
-
currentPP: userInfo.pp
|
|
2588
|
-
});
|
|
2589
|
-
await User.setDatabaseUserAttribute(userId);
|
|
2550
|
+
/** 获取层的数据 */
|
|
2551
|
+
getBaseFloorLocal(floor) {
|
|
2552
|
+
return GensokyoMap.mapLocalData[floor] || null;
|
|
2590
2553
|
},
|
|
2591
|
-
/**
|
|
2592
|
-
|
|
2593
|
-
const
|
|
2594
|
-
if (
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2554
|
+
/** 获取用户当前区域信息 */
|
|
2555
|
+
getUserCurrentArea(userid) {
|
|
2556
|
+
const { floor, areaName } = GensokyoMap.userCurrentLoal[userid] || {};
|
|
2557
|
+
if (!(floor && areaName)) return null;
|
|
2558
|
+
return GensokyoMap.mapLocalData[floor][areaName] || null;
|
|
2559
|
+
},
|
|
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
|
|
2569
|
+
};
|
|
2598
2570
|
}
|
|
2571
|
+
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
2599
2572
|
},
|
|
2600
|
-
/**
|
|
2601
|
-
async
|
|
2602
|
-
const
|
|
2603
|
-
if (
|
|
2604
|
-
const [
|
|
2605
|
-
if (
|
|
2606
|
-
|
|
2607
|
-
val: Math.abs(val),
|
|
2608
|
-
currentVal: currentM.value,
|
|
2609
|
-
err: "余额不足!"
|
|
2610
|
-
});
|
|
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);
|
|
2611
2580
|
return;
|
|
2612
2581
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
val: Math.abs(val),
|
|
2616
|
-
currentVal: currentM.value - val
|
|
2617
|
-
});
|
|
2582
|
+
delete poistionData.userId;
|
|
2583
|
+
await GensokyoMap.ctx.database.set("smm_gensokyo_map_position", { userId }, poistionData);
|
|
2618
2584
|
}
|
|
2619
2585
|
},
|
|
2620
|
-
/**
|
|
2621
|
-
async
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
if (!userProps[item.name]) {
|
|
2629
|
-
userProps[item.name] = {
|
|
2630
|
-
name: propsItem.name,
|
|
2631
|
-
type: propsItem.type,
|
|
2632
|
-
value: 0
|
|
2633
|
-
};
|
|
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;
|
|
2634
2594
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2595
|
+
if (!(floor && areaName)) {
|
|
2596
|
+
await session.send("您当前位置有误,请使用(还没写好的指令)脱离卡死...");
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
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 }
|
|
2660
2654
|
};
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
err: `道具数量不足!剩余${userProps[props.name].value}个。`
|
|
2666
|
-
});
|
|
2655
|
+
fn && await fn(areaInfo);
|
|
2656
|
+
await delay(3e3);
|
|
2657
|
+
userCurrentArea.moveing = false;
|
|
2658
|
+
GensokyoMap.setLocalStoragePoistionData(session.userId);
|
|
2667
2659
|
return;
|
|
2660
|
+
} catch (error) {
|
|
2661
|
+
console.log(error);
|
|
2662
|
+
if (GensokyoMap.userCurrentLoal?.[session.userId]) {
|
|
2663
|
+
GensokyoMap.userCurrentLoal[session.userId].moveing = false;
|
|
2664
|
+
}
|
|
2668
2665
|
}
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2666
|
+
},
|
|
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
|
+
}
|
|
2674
2678
|
});
|
|
2679
|
+
return liveUser;
|
|
2675
2680
|
},
|
|
2676
|
-
/**
|
|
2677
|
-
|
|
2678
|
-
|
|
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
|
+
}
|
|
2691
|
+
});
|
|
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;
|
|
2679
2706
|
}
|
|
2680
2707
|
};
|
|
2681
2708
|
|
|
@@ -3018,17 +3045,6 @@ function apply(ctx, config) {
|
|
|
3018
3045
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
3019
3046
|
}
|
|
3020
3047
|
GensokyoMap.move(session, "top" /* 上 */, async (val) => {
|
|
3021
|
-
if (BattleData.isTeam(session)) {
|
|
3022
|
-
const { userId } = session;
|
|
3023
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
3024
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
3025
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
3026
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
3027
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
3028
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
3029
|
-
}
|
|
3030
|
-
});
|
|
3031
|
-
}
|
|
3032
3048
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
3033
3049
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
3034
3050
|
if (random(0, 10) <= 2) {
|
|
@@ -3055,17 +3071,6 @@ function apply(ctx, config) {
|
|
|
3055
3071
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
3056
3072
|
}
|
|
3057
3073
|
GensokyoMap.move(session, "down" /* 下 */, async (val) => {
|
|
3058
|
-
if (BattleData.isTeam(session)) {
|
|
3059
|
-
const { userId } = session;
|
|
3060
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
3061
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
3062
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
3063
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
3064
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
3065
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
3066
|
-
}
|
|
3067
|
-
});
|
|
3068
|
-
}
|
|
3069
3074
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
3070
3075
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
3071
3076
|
if (random(0, 10) <= 2) {
|
|
@@ -3092,17 +3097,6 @@ function apply(ctx, config) {
|
|
|
3092
3097
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
3093
3098
|
}
|
|
3094
3099
|
GensokyoMap.move(session, "left" /* 左 */, async (val) => {
|
|
3095
|
-
if (BattleData.isTeam(session)) {
|
|
3096
|
-
const { userId } = session;
|
|
3097
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
3098
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
3099
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
3100
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
3101
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
3102
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
3103
|
-
}
|
|
3104
|
-
});
|
|
3105
|
-
}
|
|
3106
3100
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
3107
3101
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
3108
3102
|
if (random(0, 10) <= 2) {
|
|
@@ -3129,17 +3123,6 @@ function apply(ctx, config) {
|
|
|
3129
3123
|
return `你已经阵亡,请发送 /补给 进行治疗。`;
|
|
3130
3124
|
}
|
|
3131
3125
|
GensokyoMap.move(session, "right" /* 右 */, async (val) => {
|
|
3132
|
-
if (BattleData.isTeam(session)) {
|
|
3133
|
-
const { userId } = session;
|
|
3134
|
-
Object.keys(BattleData.teamTemp).forEach((_userId) => {
|
|
3135
|
-
if (BattleData.teamTemp[userId].for == userId && userId !== _userId) {
|
|
3136
|
-
GensokyoMap.userCurrentLoal[_userId].areaName = GensokyoMap.userCurrentLoal[userId].areaName;
|
|
3137
|
-
GensokyoMap.userCurrentLoal[_userId].floor = GensokyoMap.userCurrentLoal[userId].floor;
|
|
3138
|
-
GensokyoMap.userCurrentLoal[_userId].moveing = false;
|
|
3139
|
-
GensokyoMap.setLocalStoragePoistionData(_userId);
|
|
3140
|
-
}
|
|
3141
|
-
});
|
|
3142
|
-
}
|
|
3143
3126
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, val));
|
|
3144
3127
|
if (val.map.type == "冒险区" /* 冒险区 */ && val.map.monster?.length) {
|
|
3145
3128
|
if (random(0, 10) <= 2) {
|
|
@@ -3271,12 +3254,16 @@ function apply(ctx, config) {
|
|
|
3271
3254
|
const userData = await User.getUserAttribute(session);
|
|
3272
3255
|
if (!userData) return;
|
|
3273
3256
|
GensokyoMap.initUserPoistion(session, userData);
|
|
3257
|
+
if (BattleData.isBattle(session)) {
|
|
3258
|
+
await session.send("当前正在战斗,请结束后再使用改");
|
|
3259
|
+
return;
|
|
3260
|
+
}
|
|
3274
3261
|
if (temp[session.userId] == void 0) {
|
|
3275
3262
|
temp[session.userId] = 0;
|
|
3276
3263
|
}
|
|
3277
3264
|
const useTime = Date.now() - temp[session.userId];
|
|
3278
3265
|
if (useTime < 36e4) {
|
|
3279
|
-
return `请等待下一个补给时间!剩余${Math.floor(36e4 - useTime / 6e4)}分钟。`;
|
|
3266
|
+
return `请等待下一个补给时间!剩余${Math.floor((36e4 - useTime) / 6e4)}分钟。`;
|
|
3280
3267
|
}
|
|
3281
3268
|
temp[session.userId] = Date.now();
|
|
3282
3269
|
const { maxHp, maxMp, playName } = User.getUserAttributeByUserId(session.userId);
|