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.
Files changed (2) hide show
  1. package/lib/index.js +1243 -1256
  2. 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 settlement(tempData, overInfo, session) {
1850
- const allList = [...tempData.self, ...tempData.goal].filter((item) => item.type == "玩家");
1851
- const selfList = tempData.self.filter((item) => item.type == "玩家");
1852
- const goalList = tempData.goal.filter((item) => item.type == "玩家");
1853
- const msg = /* @__PURE__ */ __name(async (val) => {
1854
- const msgTemp = `${val.name}[升级]${val.lv}级!
1855
- ` + (val.atk ? `攻击力↑ ${val.atk}
1856
- ` : "") + (val.def ? `防御力↑ ${val.def}
1857
- ` : "") + (val.maxHp ? `最大血量↑ ${val.maxHp}
1858
- ` : "") + (val.maxMp ? `最大蓝量↑ ${val.maxMp}` : "");
1859
- await session.send(msgTemp);
1860
- }, "msg");
1861
- const aynchronize = /* @__PURE__ */ __name((agent) => {
1862
- User.userTempData[agent.userId].hp = agent.hp > 0 ? agent.hp : 0;
1863
- User.userTempData[agent.userId].mp = agent.mp;
1864
- if (User.userTempData[agent.userId].hp <= 0) {
1865
- User.userTempData[agent.userId].isDie = true;
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
- }, "aynchronize");
1868
- if (tempData.isPK) {
1869
- if (overInfo.win == "self") {
1870
- await session.send("攻击方获得20EXP、5货币");
1871
- for (const agent of allList) {
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
- } else {
1889
- let val = 0;
1890
- let monetary = 0;
1891
- let props = [];
1892
- const monsterName = tempData.goal.filter((item) => item.type == "怪物").map((i) => ({ name: i.name, lv: i.lv }));
1893
- monsterName.forEach((item) => {
1894
- const monster = Monster.monsterTempData[item.name];
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
- for (const agent of selfList) {
1912
- aynchronize(agent);
1913
- if (overInfo.win == "self") {
1914
- await User.giveExp(agent.userId, val, async (val2) => await msg(val2));
1915
- await User.giveMonetary(agent.userId, monetary);
1916
- props.length && await User.giveProps(agent.userId, props, async (val2) => {
1917
- const propsDict = {};
1918
- val2.currentProps.forEach((item) => {
1919
- if (!propsDict[item.name]) propsDict[item.name] = 0;
1920
- propsDict[item.name]++;
1921
- });
1922
- const msg2 = Object.keys(propsDict).map((item) => {
1923
- return `${item} ${propsDict[item]}个`;
1924
- }).join("\n");
1925
- await session.send(`${agent.name}在战斗中获得:` + msg2);
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
- function getLineupName(agent) {
1933
- return `[${agent.type}]${agent.name}`;
1934
- }
1935
- __name(getLineupName, "getLineupName");
1936
- function getSkillFn(fnList) {
1937
- const totalProb = fnList.reduce((sum, item) => sum + item.prob, 0);
1938
- const random2 = Math.random() * totalProb;
1939
- let currentProb = 0;
1940
- for (const item of fnList) {
1941
- currentProb += item.prob;
1942
- if (random2 < currentProb) {
1943
- return item.name;
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
- id: Date.now(),
1954
- userId: userData.userId,
1955
- name: userData.playName,
1956
- lv: userData.lv,
1957
- type: "玩家",
1958
- selfType: userData.type,
1959
- hp: userData.hp,
1960
- maxHp: userData.maxHp,
1961
- mp: userData.mp,
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
- return temp;
1990
- } else {
1991
- const monsterData2 = data;
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
- id: Date.now(),
1994
- name: monsterData2.name,
1995
- type: "怪物",
1996
- selfType: monsterData2.type,
1997
- lv: monsterData2.lv,
1998
- hp: monsterData2.hp,
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
- return temp;
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
- name: "蓝药",
2053
- type: "消耗类" /* 消耗类 */,
2054
- info: "回复自身20MP",
2055
- price: 10,
2056
- fn: /* @__PURE__ */ __name(async function(session) {
2057
- User.giveHPMP(session.userId, { mp: 20 }, async (val) => {
2058
- if (val.err) {
2059
- await session.send(val.err);
2060
- return;
2061
- }
2062
- const msg = `回复成功,玩家当前蓝量:${val.currentMP}`;
2063
- await session.send(msg);
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
- }, "fn")
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
- name: "初级万能药",
2069
- type: "消耗类" /* 消耗类 */,
2070
- info: "回复自身20MP和20HP",
2071
- price: 20,
2072
- fn: /* @__PURE__ */ __name(async function(session) {
2073
- User.giveHPMP(session.userId, { hp: 20, mp: 20 }, async (val) => {
2074
- if (val.err) {
2075
- await session.send(val.err);
2076
- return;
2077
- }
2078
- const msg = `回复成功,玩家当前血量:${val.currentHP}、蓝量:${val.currentMP}`;
2079
- await session.send(msg);
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
- }, "fn")
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
- name: "初级复活卷轴",
2085
- type: "消耗类" /* 消耗类 */,
2086
- info: "复活玩家,复活时保留 20% 血量。(该道具使用完需要冷却 6 分钟)",
2087
- price: 10,
2088
- cooling: 3600,
2089
- fn: /* @__PURE__ */ __name(async function(session) {
2090
- if (BattleData.isBattleByUserId(session.userId)) {
2091
- session.send(`该道具在战斗中无法使用!请在小队脱离战斗后使用。`);
2092
- return { err: true };
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
- if (!User.isDie(session.userId)) {
2095
- session.send(`您还没有阵亡,使用失败!`);
2096
- return { err: true };
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
- const { maxHp } = User.getUserAttributeByUserId(session.userId);
2099
- User.giveLife(session.userId, Math.floor(maxHp * 0.2), async (val) => {
2100
- await session.send(`复活成功,当前血量:${val.currentHP}`);
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
- }, "fn")
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/props.ts
2107
- var Props = {
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
- userPorpsTemp: {},
2264
+ mapLocalData: {},
2265
+ userCurrentLoal: {},
2111
2266
  async init(config, ctx) {
2112
- Props.config = config;
2113
- Props.ctx = ctx;
2114
- ctx.database.extend("smm_gensokyo_user_props", {
2267
+ GensokyoMap.config = config;
2268
+ GensokyoMap.ctx = ctx;
2269
+ ctx.database.extend("smm_gensokyo_map_position", {
2115
2270
  userId: "string",
2116
- props: "json"
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
- 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);
2137
- }
2138
- },
2139
- /** 获取持有道具信息 */
2140
- async getPropsDataByUserId(userId) {
2141
- await Props.initUserPropsData(userId);
2142
- const userProps = Props.userPorpsTemp[userId];
2143
- const msgList = Object.keys(userProps).map((item) => {
2144
- return `${userProps[item].name}:${userProps[item].value}个`;
2145
- });
2146
- return msgList.length ? `当前您持有如下道具:
2147
-
2148
- ` + msgList.join("\n") : "您没有任何道具...";
2149
- },
2150
- /** 更新本地数据库对应数据 */
2151
- async setDatabasePropsData(userId) {
2152
- const propsData2 = Props.userPorpsTemp[userId];
2153
- if (propsData2) {
2154
- const temp = {
2155
- props: propsData2
2156
- };
2157
- await Props.ctx.database.set("smm_gensokyo_user_props", { userId }, temp);
2158
- }
2159
- },
2160
- /** 使用指定道具 */
2161
- async userProps(session, propsName) {
2162
- const userId = session.userId;
2163
- const userPropsData = Props.userPorpsTemp[userId];
2164
- if (!userPropsData) return;
2165
- if (!userPropsData[propsName]) {
2166
- await session.send(`您似乎没有${propsName}这个道具...`);
2167
- return;
2168
- }
2169
- if (propsData[propsName].cooling) {
2170
- if (!coolingTemp[userId]) coolingTemp[userId] = {};
2171
- if (!coolingTemp[userId][propsName]) coolingTemp[userId][propsName] = 0;
2172
- const gapTime = Date.now() - coolingTemp[userId][propsName];
2173
- if (gapTime < propsData[propsName].cooling) {
2174
- await session.send(`该道具冷却还未结束,请等待${Math.ceil((coolingTemp[userId][propsName] - gapTime) / 60)}秒!`);
2175
- return;
2176
- } else {
2177
- coolingTemp[userId][propsName] = Date.now();
2178
- }
2179
- }
2180
- User.loseProps(userId, { name: propsName, val: 1 }, async (val) => {
2181
- if (val.err) {
2182
- await session.send(val.err);
2183
- return;
2184
- }
2185
- if (propsData[propsName].cooling) {
2186
- coolingTemp[userId];
2187
- }
2188
- const result = await propsData[propsName].fn(session);
2189
- if (result && typeof result === "object" && "err" in result) {
2190
- if (result.err) {
2191
- await User.giveProps(userId, [{ name: propsName, val: 1 }]);
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
- 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;
2306
- });
2307
- User.userTempData = temp;
2308
- },
2309
- /** 获取玩家名字 */
2310
- getUserName(userId) {
2311
- return User.userTempData[userId].playName || null;
2312
- },
2313
- /** 获取角色基础属性 */
2314
- async getUserAttribute(session) {
2315
- if (!User.userTempData[session.userId]) {
2316
- await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
2317
- return null;
2318
- }
2319
- return User.getUserAddLvAttribute(session.userId);
2320
- },
2321
- /** 获取角色实际等级属性数据 */
2322
- getUserAddLvAttribute(userId) {
2323
- const UserDict = User.userTempData[userId];
2324
- if (!UserDict) return null;
2325
- const UserData = {
2326
- ...UserOccDict[UserDict.type].initStatus,
2327
- lv: UserDict.lv,
2328
- hp: UserDict.hp,
2329
- mp: UserDict.mp,
2330
- exp: UserDict.exp,
2331
- pp: UserDict.pp,
2332
- playName: UserDict.playName,
2333
- userId: UserDict.userId
2334
- };
2335
- const lv = UserData.lv;
2336
- const temp = {};
2337
- const lvScope = Object.keys(userBenchmark).reverse().find((item) => Number(item) < lv) || 10;
2338
- const useBenchmark = userBenchmark[lvScope];
2339
- Object.keys(UserData).forEach((i) => {
2340
- temp[i] = UserData[i];
2341
- if (useBenchmark[i]) {
2342
- if (i == "maxExp") {
2343
- temp[i] = Math.floor(100 * useBenchmark[i] * (lv - 1)) || 100;
2344
- } else {
2345
- temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
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
- User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
2438
- },
2439
- /** 给予玩家经验 */
2440
- async giveExp(userId, value, fn) {
2441
- const userInfo = User.userTempData[userId];
2442
- if (!userInfo) return;
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
- await User.setDatabaseUserAttribute(userId);
2548
+ GensokyoMap.userCurrentLoal = poistionTemp;
2574
2549
  },
2575
- async lostPP(userId, value, fn) {
2576
- const userInfo = User.userTempData[userId];
2577
- if (!userInfo) return;
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
- async giveMonetary(userId, val, fn) {
2593
- const [bindData] = await User.ctx.database.get("binding", { pid: userId });
2594
- if (bindData && val) {
2595
- const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
2596
- await User.ctx.monetary.gain(bindData.aid, val);
2597
- fn && await fn({ val, currentVal: currentM.value += val });
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 lostMonetary(userId, val, fn) {
2602
- const [bindData] = await User.ctx.database.get("binding", { pid: userId });
2603
- if (bindData && val) {
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
- });
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
- await User.ctx.monetary.cost(bindData.aid, val);
2614
- fn && await fn({
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 giveProps(userId, props, fn) {
2622
- const userProps = Props.userPorpsTemp[userId];
2623
- if (!userProps) return;
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
- };
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
- userProps[item.name].value += item.val || 1;
2636
- upProps.push({ name: item.name, val: userProps[item.name].value });
2637
- }
2638
- await Props.setDatabasePropsData(userId);
2639
- fn && await fn({
2640
- currentProps: upProps
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;
2654
- }
2655
- if (!userProps[props.name]) {
2656
- userProps[props.name] = {
2657
- name: propsItem.name,
2658
- type: propsItem.type,
2659
- value: 0
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
- if (userProps[props.name].value - (props.val || 1) < 0) {
2663
- fn && await fn({
2664
- currentProps: { name: props.name, val: userProps[props.name].value },
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
- 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 }
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
- isDie(userId) {
2678
- return User.userTempData[userId]?.isDie;
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);