koishi-plugin-smmcat-gensokyo 0.0.13 → 0.0.15
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/data/benchmark.d.ts +56 -0
- package/lib/data/initMonster.d.ts +61 -59
- package/lib/data/initProps.d.ts +16 -0
- package/lib/index.js +1033 -614
- package/lib/monster.d.ts +1 -44
- package/lib/props.d.ts +37 -0
- package/lib/skillFn.d.ts +5 -1
- package/lib/users.d.ts +58 -29
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -191,6 +191,7 @@ var GensokyoMap = {
|
|
|
191
191
|
floor: 1,
|
|
192
192
|
areaName: "绿野平原三",
|
|
193
193
|
type: "冒险区" /* 冒险区 */,
|
|
194
|
+
monster: [{ name: "dora", lv: 5 }],
|
|
194
195
|
needLv: 1,
|
|
195
196
|
left: "绿野平原一",
|
|
196
197
|
down: "绿野平原六"
|
|
@@ -361,412 +362,328 @@ var GensokyoMap = {
|
|
|
361
362
|
}
|
|
362
363
|
};
|
|
363
364
|
|
|
364
|
-
// src/
|
|
365
|
-
var
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
365
|
+
// src/data/benchmark.ts
|
|
366
|
+
var monsterBenchmark = {
|
|
367
|
+
10: {
|
|
368
|
+
hp: 1.4,
|
|
369
|
+
maxHp: 1.4,
|
|
370
|
+
mp: 1.2,
|
|
371
|
+
maxMp: 1.2,
|
|
372
|
+
atk: 1.2,
|
|
373
|
+
def: 1.1,
|
|
374
|
+
chr: 1.1,
|
|
375
|
+
evasion: 1.1,
|
|
376
|
+
hit: 1.1,
|
|
377
|
+
ghd: 1,
|
|
378
|
+
speed: 1.05
|
|
379
|
+
},
|
|
380
|
+
20: {
|
|
381
|
+
hp: 1.35,
|
|
382
|
+
maxHp: 1.35,
|
|
383
|
+
mp: 1.1,
|
|
384
|
+
maxMp: 1.1,
|
|
385
|
+
atk: 1.1,
|
|
386
|
+
def: 1.1,
|
|
387
|
+
chr: 1.08,
|
|
388
|
+
evasion: 1.08,
|
|
389
|
+
hit: 1.08,
|
|
390
|
+
ghd: 1,
|
|
391
|
+
speed: 1.05
|
|
392
|
+
},
|
|
393
|
+
40: {
|
|
394
|
+
hp: 1.2,
|
|
395
|
+
maxHp: 1.2,
|
|
396
|
+
mp: 1.05,
|
|
397
|
+
maxMp: 1.05,
|
|
398
|
+
atk: 1.1,
|
|
399
|
+
def: 1.05,
|
|
400
|
+
chr: 1.05,
|
|
401
|
+
evasion: 1.05,
|
|
402
|
+
hit: 1.05,
|
|
403
|
+
ghd: 1.05,
|
|
404
|
+
speed: 1.05
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
var userBenchmark = {
|
|
408
|
+
10: {
|
|
409
|
+
maxExp: 2,
|
|
410
|
+
maxHp: 1.2,
|
|
411
|
+
maxMp: 1.1,
|
|
412
|
+
atk: 1.12,
|
|
413
|
+
def: 1.1,
|
|
414
|
+
chr: 1.08,
|
|
415
|
+
evasion: 1.08,
|
|
416
|
+
hit: 1.08,
|
|
417
|
+
ghd: 1,
|
|
418
|
+
speed: 1.05
|
|
419
|
+
},
|
|
420
|
+
20: {
|
|
421
|
+
maxExp: 1.8,
|
|
422
|
+
maxHp: 1.15,
|
|
423
|
+
maxMp: 1.1,
|
|
424
|
+
atk: 1.1,
|
|
425
|
+
def: 1.1,
|
|
426
|
+
chr: 1.04,
|
|
427
|
+
evasion: 1.04,
|
|
428
|
+
hit: 1.04,
|
|
429
|
+
ghd: 1,
|
|
430
|
+
speed: 1.05
|
|
431
|
+
},
|
|
432
|
+
40: {
|
|
433
|
+
maxExp: 1.5,
|
|
434
|
+
maxHp: 1.1,
|
|
435
|
+
maxMp: 1.05,
|
|
436
|
+
atk: 1.1,
|
|
437
|
+
def: 1.05,
|
|
438
|
+
chr: 1.03,
|
|
439
|
+
evasion: 1.03,
|
|
440
|
+
hit: 1.03,
|
|
441
|
+
ghd: 1.05,
|
|
442
|
+
speed: 1.05
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
// src/data/initProps.ts
|
|
447
|
+
var propsData = {
|
|
448
|
+
"红药": {
|
|
449
|
+
name: "红药",
|
|
450
|
+
type: "消耗类" /* 消耗类 */,
|
|
451
|
+
info: "回复自身20HP",
|
|
452
|
+
price: 10,
|
|
453
|
+
fn: /* @__PURE__ */ __name(function(session) {
|
|
454
|
+
User.giveHPMP(session.userId, { hp: 20 }, async (val) => {
|
|
455
|
+
if (val.err) {
|
|
456
|
+
await session.send(val.err);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const msg = `回复成功,玩家当前血量:${val.currentHP}`;
|
|
460
|
+
await session.send(msg);
|
|
461
|
+
});
|
|
462
|
+
}, "fn")
|
|
463
|
+
},
|
|
464
|
+
"蓝药": {
|
|
465
|
+
name: "蓝药",
|
|
466
|
+
type: "消耗类" /* 消耗类 */,
|
|
467
|
+
info: "回复自身20MP",
|
|
468
|
+
price: 10,
|
|
469
|
+
fn: /* @__PURE__ */ __name(function(session) {
|
|
470
|
+
User.giveHPMP(session.userId, { mp: 20 }, async (val) => {
|
|
471
|
+
if (val.err) {
|
|
472
|
+
await session.send(val.err);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const msg = `回复成功,玩家当前蓝量:${val.currentMP}`;
|
|
476
|
+
await session.send(msg);
|
|
477
|
+
});
|
|
478
|
+
}, "fn")
|
|
479
|
+
},
|
|
480
|
+
"初级万能药": {
|
|
481
|
+
name: "初级万能药",
|
|
482
|
+
type: "消耗类" /* 消耗类 */,
|
|
483
|
+
info: "回复自身20MP和20HP",
|
|
484
|
+
price: 20,
|
|
485
|
+
fn: /* @__PURE__ */ __name(function(session) {
|
|
486
|
+
User.giveHPMP(session.userId, { hp: 20, mp: 20 }, async (val) => {
|
|
487
|
+
if (val.err) {
|
|
488
|
+
await session.send(val.err);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const msg = `回复成功,玩家当前血量:${val.currentHP}、蓝量:${val.currentMP}`;
|
|
492
|
+
await session.send(msg);
|
|
493
|
+
});
|
|
494
|
+
}, "fn")
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
// src/props.ts
|
|
499
|
+
var Props = {
|
|
500
|
+
config: {},
|
|
501
|
+
ctx: {},
|
|
502
|
+
userPorpsTemp: {},
|
|
503
|
+
async init(config, ctx) {
|
|
504
|
+
Props.config = config;
|
|
505
|
+
Props.ctx = ctx;
|
|
506
|
+
ctx.database.extend("smm_gensokyo_user_props", {
|
|
507
|
+
userId: "string",
|
|
508
|
+
props: "json"
|
|
509
|
+
}, {
|
|
510
|
+
primary: "userId",
|
|
511
|
+
autoInc: false
|
|
512
|
+
});
|
|
513
|
+
const temp = {};
|
|
514
|
+
const propsList = await ctx.database.get("smm_gensokyo_user_props", {});
|
|
515
|
+
propsList.forEach((item) => {
|
|
516
|
+
temp[item.userId] = item.props;
|
|
517
|
+
});
|
|
518
|
+
Props.userPorpsTemp = temp;
|
|
519
|
+
},
|
|
520
|
+
/** 创建本地数据 */
|
|
521
|
+
async initUserPropsData(userId) {
|
|
522
|
+
if (!Props.userPorpsTemp[userId]) {
|
|
523
|
+
Props.userPorpsTemp[userId] = {};
|
|
524
|
+
const temp = {
|
|
525
|
+
userId,
|
|
526
|
+
props: {}
|
|
527
|
+
};
|
|
528
|
+
await Props.ctx.database.create("smm_gensokyo_user_props", temp);
|
|
389
529
|
}
|
|
390
530
|
},
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
ghd: 1.2,
|
|
411
|
-
speed: 5,
|
|
412
|
-
evasion: 100,
|
|
413
|
-
hit: 100
|
|
531
|
+
/** 获取持有道具信息 */
|
|
532
|
+
async getPropsDataByUserId(userId) {
|
|
533
|
+
await Props.initUserPropsData(userId);
|
|
534
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
535
|
+
const msgList = Object.keys(userProps).map((item) => {
|
|
536
|
+
return `${userProps[item].name}:${userProps[item].value}个`;
|
|
537
|
+
});
|
|
538
|
+
return msgList.length ? `当前您持有如下道具:
|
|
539
|
+
|
|
540
|
+
` + msgList.join("\n") : "您没有任何道具...";
|
|
541
|
+
},
|
|
542
|
+
/** 更新本地数据库对应数据 */
|
|
543
|
+
async setDatabasePropsData(userId) {
|
|
544
|
+
const propsData2 = Props.userPorpsTemp[userId];
|
|
545
|
+
if (propsData2) {
|
|
546
|
+
const temp = {
|
|
547
|
+
props: propsData2
|
|
548
|
+
};
|
|
549
|
+
await Props.ctx.database.set("smm_gensokyo_user_props", { userId }, temp);
|
|
414
550
|
}
|
|
415
551
|
},
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
exp: 0,
|
|
423
|
-
maxExp: 100,
|
|
424
|
-
lv: 1,
|
|
425
|
-
hp: 90,
|
|
426
|
-
maxHp: 90,
|
|
427
|
-
mp: 70,
|
|
428
|
-
maxMp: 70,
|
|
429
|
-
pp: 100,
|
|
430
|
-
maxPp: 100,
|
|
431
|
-
atk: 8,
|
|
432
|
-
def: 2,
|
|
433
|
-
chr: 80,
|
|
434
|
-
csr: 0,
|
|
435
|
-
ghd: 1.3,
|
|
436
|
-
speed: 6,
|
|
437
|
-
evasion: 120,
|
|
438
|
-
hit: 100
|
|
552
|
+
async userProps(session, propsName) {
|
|
553
|
+
const userPropsData = Props.userPorpsTemp[session.userId];
|
|
554
|
+
if (!userPropsData) return;
|
|
555
|
+
if (!userPropsData[propsName]) {
|
|
556
|
+
await session.send(`您似乎没有${propsName}这个道具...`);
|
|
557
|
+
return;
|
|
439
558
|
}
|
|
559
|
+
User.loseProps(session.userId, { name: propsName, val: 1 }, async (val) => {
|
|
560
|
+
if (val.err) {
|
|
561
|
+
await session.send(val.err);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
propsData[propsName].fn(session);
|
|
565
|
+
});
|
|
440
566
|
}
|
|
441
567
|
};
|
|
442
|
-
|
|
568
|
+
|
|
569
|
+
// src/monster.ts
|
|
570
|
+
var import_koishi = require("koishi");
|
|
571
|
+
|
|
572
|
+
// src/data/initMonster.ts
|
|
573
|
+
var monsterData = {
|
|
574
|
+
"小蜜蜂": {
|
|
575
|
+
name: "小蜜蜂",
|
|
576
|
+
type: "野怪" /* 野怪 */,
|
|
577
|
+
info: "幻想乡一层常见的生物",
|
|
578
|
+
pic: "http://smmcat.cn/run/gensokyo/小蜜蜂.png",
|
|
579
|
+
hp: 50,
|
|
580
|
+
maxHp: 50,
|
|
581
|
+
mp: 30,
|
|
582
|
+
maxMp: 30,
|
|
583
|
+
atk: 7,
|
|
584
|
+
def: 2,
|
|
585
|
+
chr: 50,
|
|
586
|
+
csr: 0,
|
|
587
|
+
evasion: 100,
|
|
588
|
+
hit: 1e3,
|
|
589
|
+
ghd: 1.2,
|
|
590
|
+
speed: 4,
|
|
591
|
+
giveExp: 10,
|
|
592
|
+
giveMonetary: 2,
|
|
593
|
+
giveProps: [
|
|
594
|
+
{ name: "红药", val: 3, radomVal: 30 }
|
|
595
|
+
]
|
|
596
|
+
},
|
|
597
|
+
"小蜘蛛": {
|
|
598
|
+
name: "小蜘蛛",
|
|
599
|
+
type: "野怪" /* 野怪 */,
|
|
600
|
+
info: "幻想乡一层常见的生物",
|
|
601
|
+
pic: "http://smmcat.cn/run/gensokyo/小蜘蛛.png",
|
|
602
|
+
hp: 55,
|
|
603
|
+
maxHp: 55,
|
|
604
|
+
mp: 30,
|
|
605
|
+
maxMp: 30,
|
|
606
|
+
atk: 10,
|
|
607
|
+
def: 3,
|
|
608
|
+
chr: 50,
|
|
609
|
+
csr: 0,
|
|
610
|
+
evasion: 150,
|
|
611
|
+
hit: 1e3,
|
|
612
|
+
ghd: 1.2,
|
|
613
|
+
speed: 4,
|
|
614
|
+
giveExp: 12,
|
|
615
|
+
giveMonetary: 2,
|
|
616
|
+
giveProps: [
|
|
617
|
+
{ name: "蓝药", val: 3, radomVal: 30 }
|
|
618
|
+
]
|
|
619
|
+
},
|
|
620
|
+
"dora": {
|
|
621
|
+
name: "dora",
|
|
622
|
+
type: "野怪" /* 野怪 */,
|
|
623
|
+
info: "偶尔出没在一层世界的奇怪生物",
|
|
624
|
+
pic: "http://smmcat.cn/run/gensokyo/dora.png",
|
|
625
|
+
hp: 88,
|
|
626
|
+
maxHp: 88,
|
|
627
|
+
mp: 10,
|
|
628
|
+
maxMp: 10,
|
|
629
|
+
atk: 20,
|
|
630
|
+
def: 5,
|
|
631
|
+
chr: 200,
|
|
632
|
+
csr: 0,
|
|
633
|
+
evasion: 200,
|
|
634
|
+
hit: 1e3,
|
|
635
|
+
ghd: 1.2,
|
|
636
|
+
speed: 4,
|
|
637
|
+
giveExp: 15,
|
|
638
|
+
giveMonetary: 3,
|
|
639
|
+
giveProps: [
|
|
640
|
+
{ name: "蓝药", val: 3, radomVal: 30 },
|
|
641
|
+
{ name: "初级万能药", val: 2, radomVal: 90, const: true, lv: 5 }
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
// src/monster.ts
|
|
647
|
+
var Monster = {
|
|
443
648
|
config: {},
|
|
444
649
|
ctx: {},
|
|
445
|
-
|
|
650
|
+
monsterTempData: {},
|
|
446
651
|
async init(config, ctx) {
|
|
447
|
-
|
|
448
|
-
|
|
652
|
+
Monster.config = config;
|
|
653
|
+
Monster.ctx = ctx;
|
|
449
654
|
ctx.model.extend(
|
|
450
|
-
"
|
|
655
|
+
"smm_gensokyo_monster_attribute",
|
|
451
656
|
{
|
|
452
|
-
|
|
453
|
-
|
|
657
|
+
id: "integer",
|
|
658
|
+
name: "string",
|
|
659
|
+
info: "string",
|
|
454
660
|
type: "string",
|
|
455
|
-
exp: "integer",
|
|
456
|
-
lv: "integer",
|
|
457
661
|
hp: "integer",
|
|
662
|
+
maxHp: "integer",
|
|
458
663
|
mp: "integer",
|
|
459
|
-
|
|
664
|
+
maxMp: "integer",
|
|
665
|
+
atk: "integer",
|
|
666
|
+
def: "integer",
|
|
667
|
+
chr: "integer",
|
|
668
|
+
evasion: "integer",
|
|
669
|
+
hit: "integer",
|
|
670
|
+
ghd: "integer",
|
|
671
|
+
speed: "integer"
|
|
460
672
|
},
|
|
461
673
|
{
|
|
462
|
-
primary: "
|
|
674
|
+
primary: "id",
|
|
463
675
|
autoInc: false
|
|
464
676
|
}
|
|
465
677
|
);
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
if (!User.userTempData[session.userId]) {
|
|
476
|
-
await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
|
|
477
|
-
return null;
|
|
478
|
-
}
|
|
479
|
-
return User.getUserAddLvAttribute(session.userId);
|
|
480
|
-
},
|
|
481
|
-
/** 获取角色实际等级属性数据 */
|
|
482
|
-
getUserAddLvAttribute(userId) {
|
|
483
|
-
const UserDict = User.userTempData[userId];
|
|
484
|
-
if (!UserDict) return null;
|
|
485
|
-
const UserData = {
|
|
486
|
-
...UserOccDict[UserDict.type].initStatus,
|
|
487
|
-
lv: UserDict.lv,
|
|
488
|
-
hp: UserDict.hp,
|
|
489
|
-
mp: UserDict.mp,
|
|
490
|
-
exp: UserDict.exp,
|
|
491
|
-
pp: UserDict.pp,
|
|
492
|
-
playName: UserDict.playName,
|
|
493
|
-
userId: UserDict.userId
|
|
494
|
-
};
|
|
495
|
-
const lv = UserData.lv;
|
|
496
|
-
const benchmark = {
|
|
497
|
-
10: {
|
|
498
|
-
maxExp: 2,
|
|
499
|
-
maxHp: 1.2,
|
|
500
|
-
maxMp: 1.1,
|
|
501
|
-
atk: 1.12,
|
|
502
|
-
def: 1.1,
|
|
503
|
-
chr: 1.08,
|
|
504
|
-
evasion: 1.08,
|
|
505
|
-
hit: 1.08,
|
|
506
|
-
ghd: 1,
|
|
507
|
-
speed: 1.05
|
|
508
|
-
},
|
|
509
|
-
20: {
|
|
510
|
-
maxExp: 1.8,
|
|
511
|
-
maxHp: 1.15,
|
|
512
|
-
maxMp: 1.1,
|
|
513
|
-
atk: 1.1,
|
|
514
|
-
def: 1.1,
|
|
515
|
-
chr: 1.04,
|
|
516
|
-
evasion: 1.04,
|
|
517
|
-
hit: 1.04,
|
|
518
|
-
ghd: 1,
|
|
519
|
-
speed: 1.05
|
|
520
|
-
},
|
|
521
|
-
40: {
|
|
522
|
-
maxExp: 1.5,
|
|
523
|
-
maxHp: 1.1,
|
|
524
|
-
maxMp: 1.05,
|
|
525
|
-
atk: 1.1,
|
|
526
|
-
def: 1.05,
|
|
527
|
-
chr: 1.03,
|
|
528
|
-
evasion: 1.03,
|
|
529
|
-
hit: 1.03,
|
|
530
|
-
ghd: 1.05,
|
|
531
|
-
speed: 1.05
|
|
532
|
-
}
|
|
533
|
-
};
|
|
534
|
-
const temp = {};
|
|
535
|
-
const lvScope = Object.keys(benchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
536
|
-
const useBenchmark = benchmark[lvScope];
|
|
537
|
-
Object.keys(UserData).forEach((i) => {
|
|
538
|
-
temp[i] = UserData[i];
|
|
539
|
-
if (useBenchmark[i]) {
|
|
540
|
-
if (i == "maxExp") {
|
|
541
|
-
temp[i] = Math.floor(100 * useBenchmark[i] * (lv - 1)) || 100;
|
|
542
|
-
} else {
|
|
543
|
-
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
return temp;
|
|
548
|
-
},
|
|
549
|
-
/** 通过 userId 获取角色属性 */
|
|
550
|
-
getUserAttributeByUserId(userId) {
|
|
551
|
-
return User.getUserAddLvAttribute(userId) || null;
|
|
552
|
-
},
|
|
553
|
-
/** 创建游戏账号 */
|
|
554
|
-
async createPlayUser(session) {
|
|
555
|
-
const [data] = await User.ctx.database.get("smm_gensokyo_user_attribute", { userId: session.userId });
|
|
556
|
-
if (data) {
|
|
557
|
-
await session.send("已存在账号,请勿重复创建!");
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
await session.send("请输入自己的游戏昵称:(60s)");
|
|
561
|
-
const playname = await session.prompt(6e4);
|
|
562
|
-
if (playname == void 0) return;
|
|
563
|
-
const [repeat] = await User.ctx.database.get("smm_gensokyo_user_attribute", { playName: playname.trim() });
|
|
564
|
-
if (repeat) {
|
|
565
|
-
await session.send("名字重复,请更换一个名字。");
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
if (playname.trim().length > 6 || playname.trim().length < 1) {
|
|
569
|
-
await session.send("名字长度有问题,要求小于 6个字,大于 1个字");
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
await session.send(`请输入要专职的职业:(60s)
|
|
573
|
-
${Object.keys(UserOccDict).map((i) => `【${i}】:${UserOccDict[i].info}`).join("\n")}`);
|
|
574
|
-
let jobType = await session.prompt(6e4);
|
|
575
|
-
if (jobType == void 0) return;
|
|
576
|
-
while (!Object.keys(UserOccDict).includes(jobType)) {
|
|
577
|
-
await session.send("未找到该职业,请重新选择!");
|
|
578
|
-
jobType = await session.prompt(6e4);
|
|
579
|
-
}
|
|
580
|
-
const temp = {
|
|
581
|
-
userId: session.userId,
|
|
582
|
-
playName: playname.trim(),
|
|
583
|
-
type: jobType,
|
|
584
|
-
hp: UserOccDict[jobType].initStatus.hp,
|
|
585
|
-
pp: UserOccDict[jobType].initStatus.pp,
|
|
586
|
-
mp: UserOccDict[jobType].initStatus.mp,
|
|
587
|
-
lv: 1,
|
|
588
|
-
exp: 0
|
|
589
|
-
};
|
|
590
|
-
User.ctx.database.create("smm_gensokyo_user_attribute", temp);
|
|
591
|
-
User.userTempData[session.userId] = temp;
|
|
592
|
-
await session.send("创建成功!\n" + User.userAttributeTextFormat(session.userId));
|
|
593
|
-
},
|
|
594
|
-
/** 信息格式化 */
|
|
595
|
-
userAttributeTextFormat(userId) {
|
|
596
|
-
if (!User.userTempData[userId]) {
|
|
597
|
-
return "没有找到您的角色信息";
|
|
598
|
-
}
|
|
599
|
-
const temp = User.getUserAttributeByUserId(userId);
|
|
600
|
-
return `昵称:${temp.playName}
|
|
601
|
-
职位:${temp.type}
|
|
602
|
-
等级:${temp.lv} (${temp.exp}/${temp.maxExp})
|
|
603
|
-
-----------------
|
|
604
|
-
【生命值】${temp.hp}/${temp.maxHp}
|
|
605
|
-
【魔法值】${temp.mp}/${temp.maxMp}
|
|
606
|
-
【活力值】${temp.pp}/${temp.maxPp}
|
|
607
|
-
-----------------
|
|
608
|
-
【攻击力】${temp.atk} (+0)
|
|
609
|
-
【防御力】${temp.def} (+0)
|
|
610
|
-
【速度值】${temp.speed} (+0)
|
|
611
|
-
【闪避值】${temp.evasion} (+0)
|
|
612
|
-
【命中率】${(temp.hit / 10 + 100).toFixed(1)}% (+0%)
|
|
613
|
-
【暴击率】${(temp.chr / 10).toFixed(1)}% (+0%)
|
|
614
|
-
【暴击伤害】${(temp.ghd * 100).toFixed(1)}% (+0%)` + (temp.csr > 0 ? `
|
|
615
|
-
【暴击抵抗】${temp.csr}` : "");
|
|
616
|
-
},
|
|
617
|
-
/** 写入用户数据到数据库 */
|
|
618
|
-
async setDatabaseUserAttribute(userId) {
|
|
619
|
-
const userInfo = User.userTempData[userId];
|
|
620
|
-
if (!userInfo) return;
|
|
621
|
-
const temp = {
|
|
622
|
-
playName: userInfo.playName.trim(),
|
|
623
|
-
hp: userInfo.hp,
|
|
624
|
-
pp: userInfo.pp,
|
|
625
|
-
mp: userInfo.mp,
|
|
626
|
-
lv: userInfo.lv,
|
|
627
|
-
exp: userInfo.exp
|
|
628
|
-
};
|
|
629
|
-
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
630
|
-
},
|
|
631
|
-
/** 给予玩家经验 */
|
|
632
|
-
async giveExp(userId, value, fn) {
|
|
633
|
-
const userInfo = User.userTempData[userId];
|
|
634
|
-
if (!userInfo) return;
|
|
635
|
-
const beforData = { ...User.getUserAttributeByUserId(userId) };
|
|
636
|
-
let isUp = false;
|
|
637
|
-
userInfo.exp += value;
|
|
638
|
-
while (true) {
|
|
639
|
-
const { maxExp } = User.getUserAttributeByUserId(userId);
|
|
640
|
-
if (userInfo.exp < maxExp) break;
|
|
641
|
-
userInfo.lv += 1;
|
|
642
|
-
userInfo.exp -= maxExp;
|
|
643
|
-
isUp = true;
|
|
644
|
-
}
|
|
645
|
-
if (isUp) {
|
|
646
|
-
const afterData = User.getUserAttributeByUserId(userId);
|
|
647
|
-
const upTemp = {
|
|
648
|
-
name: afterData.playName,
|
|
649
|
-
lv: afterData.lv,
|
|
650
|
-
maxHp: afterData.maxHp - beforData.maxHp,
|
|
651
|
-
maxMp: afterData.maxMp = beforData.maxMp,
|
|
652
|
-
atk: afterData.atk - beforData.atk,
|
|
653
|
-
def: afterData.def - beforData.def
|
|
654
|
-
};
|
|
655
|
-
fn && await fn(upTemp);
|
|
656
|
-
}
|
|
657
|
-
await User.setDatabaseUserAttribute(userId);
|
|
658
|
-
},
|
|
659
|
-
/** 目标是否死亡 */
|
|
660
|
-
isDie(userId) {
|
|
661
|
-
return User.userTempData[userId]?.hp <= 0;
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
|
|
665
|
-
// src/monster.ts
|
|
666
|
-
var import_koishi = require("koishi");
|
|
667
|
-
|
|
668
|
-
// src/data/initMonster.ts
|
|
669
|
-
var monsterData = {
|
|
670
|
-
"小蜜蜂": {
|
|
671
|
-
name: "小蜜蜂",
|
|
672
|
-
type: "野怪" /* 野怪 */,
|
|
673
|
-
info: "幻想乡一层常见的生物",
|
|
674
|
-
pic: "http://smmcat.cn/run/gensokyo/小蜜蜂.png",
|
|
675
|
-
hp: 50,
|
|
676
|
-
maxHp: 50,
|
|
677
|
-
mp: 30,
|
|
678
|
-
maxMp: 30,
|
|
679
|
-
atk: 7,
|
|
680
|
-
def: 2,
|
|
681
|
-
chr: 50,
|
|
682
|
-
csr: 0,
|
|
683
|
-
evasion: 100,
|
|
684
|
-
hit: 1e3,
|
|
685
|
-
ghd: 1.2,
|
|
686
|
-
speed: 4,
|
|
687
|
-
giveExp: 10
|
|
688
|
-
},
|
|
689
|
-
"小蜘蛛": {
|
|
690
|
-
name: "小蜘蛛",
|
|
691
|
-
type: "野怪" /* 野怪 */,
|
|
692
|
-
info: "幻想乡一层常见的生物",
|
|
693
|
-
pic: "http://smmcat.cn/run/gensokyo/小蜘蛛.png",
|
|
694
|
-
hp: 55,
|
|
695
|
-
maxHp: 55,
|
|
696
|
-
mp: 30,
|
|
697
|
-
maxMp: 30,
|
|
698
|
-
atk: 10,
|
|
699
|
-
def: 3,
|
|
700
|
-
chr: 50,
|
|
701
|
-
csr: 0,
|
|
702
|
-
evasion: 150,
|
|
703
|
-
hit: 1e3,
|
|
704
|
-
ghd: 1.2,
|
|
705
|
-
speed: 4,
|
|
706
|
-
giveExp: 12
|
|
707
|
-
},
|
|
708
|
-
"dora": {
|
|
709
|
-
name: "dora",
|
|
710
|
-
type: "野怪" /* 野怪 */,
|
|
711
|
-
info: "偶尔出没在一层世界的奇怪生物",
|
|
712
|
-
pic: "http://smmcat.cn/run/gensokyo/dora.png",
|
|
713
|
-
hp: 88,
|
|
714
|
-
maxHp: 88,
|
|
715
|
-
mp: 10,
|
|
716
|
-
maxMp: 10,
|
|
717
|
-
atk: 20,
|
|
718
|
-
def: 5,
|
|
719
|
-
chr: 200,
|
|
720
|
-
csr: 0,
|
|
721
|
-
evasion: 200,
|
|
722
|
-
hit: 1e3,
|
|
723
|
-
ghd: 1.2,
|
|
724
|
-
speed: 4,
|
|
725
|
-
giveExp: 15
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
|
|
729
|
-
// src/monster.ts
|
|
730
|
-
var Monster = {
|
|
731
|
-
config: {},
|
|
732
|
-
ctx: {},
|
|
733
|
-
monsterTempData: {},
|
|
734
|
-
async init(config, ctx) {
|
|
735
|
-
Monster.config = config;
|
|
736
|
-
Monster.ctx = ctx;
|
|
737
|
-
ctx.model.extend(
|
|
738
|
-
"smm_gensokyo_monster_attribute",
|
|
739
|
-
{
|
|
740
|
-
id: "integer",
|
|
741
|
-
name: "string",
|
|
742
|
-
info: "string",
|
|
743
|
-
type: "string",
|
|
744
|
-
hp: "integer",
|
|
745
|
-
maxHp: "integer",
|
|
746
|
-
mp: "integer",
|
|
747
|
-
maxMp: "integer",
|
|
748
|
-
atk: "integer",
|
|
749
|
-
def: "integer",
|
|
750
|
-
chr: "integer",
|
|
751
|
-
evasion: "integer",
|
|
752
|
-
hit: "integer",
|
|
753
|
-
ghd: "integer",
|
|
754
|
-
speed: "integer"
|
|
755
|
-
},
|
|
756
|
-
{
|
|
757
|
-
primary: "id",
|
|
758
|
-
autoInc: false
|
|
759
|
-
}
|
|
760
|
-
);
|
|
761
|
-
const monsterData2 = await ctx.database.get("smm_gensokyo_monster_attribute", {});
|
|
762
|
-
if (monsterData2.length == 0) {
|
|
763
|
-
Monster.monsterTempData = Monster._createInitMonsterData();
|
|
764
|
-
} else {
|
|
765
|
-
const temp = {};
|
|
766
|
-
monsterData2.forEach((item) => {
|
|
767
|
-
temp[item.id] = item;
|
|
768
|
-
});
|
|
769
|
-
Monster.monsterTempData = temp;
|
|
678
|
+
const monsterData2 = await ctx.database.get("smm_gensokyo_monster_attribute", {});
|
|
679
|
+
if (monsterData2.length == 0) {
|
|
680
|
+
Monster.monsterTempData = Monster._createInitMonsterData();
|
|
681
|
+
} else {
|
|
682
|
+
const temp = {};
|
|
683
|
+
monsterData2.forEach((item) => {
|
|
684
|
+
temp[item.id] = item;
|
|
685
|
+
});
|
|
686
|
+
Monster.monsterTempData = temp;
|
|
770
687
|
}
|
|
771
688
|
},
|
|
772
689
|
/** 赋予原始的怪物数据 */
|
|
@@ -776,50 +693,9 @@ var Monster = {
|
|
|
776
693
|
getMonsterAttributeData(monsterName, lv) {
|
|
777
694
|
const monster = Monster.monsterTempData[monsterName];
|
|
778
695
|
if (!monster) return null;
|
|
779
|
-
const benchmark = {
|
|
780
|
-
10: {
|
|
781
|
-
hp: 1.4,
|
|
782
|
-
maxHp: 1.4,
|
|
783
|
-
mp: 1.2,
|
|
784
|
-
maxMp: 1.2,
|
|
785
|
-
atk: 1.2,
|
|
786
|
-
def: 1.1,
|
|
787
|
-
chr: 1.1,
|
|
788
|
-
evasion: 1.1,
|
|
789
|
-
hit: 1.1,
|
|
790
|
-
ghd: 1,
|
|
791
|
-
speed: 1.05
|
|
792
|
-
},
|
|
793
|
-
20: {
|
|
794
|
-
hp: 1.35,
|
|
795
|
-
maxHp: 1.35,
|
|
796
|
-
mp: 1.1,
|
|
797
|
-
maxMp: 1.1,
|
|
798
|
-
atk: 1.1,
|
|
799
|
-
def: 1.1,
|
|
800
|
-
chr: 1.08,
|
|
801
|
-
evasion: 1.08,
|
|
802
|
-
hit: 1.08,
|
|
803
|
-
ghd: 1,
|
|
804
|
-
speed: 1.05
|
|
805
|
-
},
|
|
806
|
-
40: {
|
|
807
|
-
hp: 1.2,
|
|
808
|
-
maxHp: 1.2,
|
|
809
|
-
mp: 1.05,
|
|
810
|
-
maxMp: 1.05,
|
|
811
|
-
atk: 1.1,
|
|
812
|
-
def: 1.05,
|
|
813
|
-
chr: 1.05,
|
|
814
|
-
evasion: 1.05,
|
|
815
|
-
hit: 1.05,
|
|
816
|
-
ghd: 1.05,
|
|
817
|
-
speed: 1.05
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
696
|
const temp = { lv };
|
|
821
|
-
const lvScope = Object.keys(
|
|
822
|
-
const useBenchmark =
|
|
697
|
+
const lvScope = Object.keys(monsterBenchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
698
|
+
const useBenchmark = monsterBenchmark[lvScope];
|
|
823
699
|
console.log(useBenchmark);
|
|
824
700
|
Object.keys(monster).forEach((i) => {
|
|
825
701
|
temp[i] = monster[i];
|
|
@@ -831,7 +707,8 @@ var Monster = {
|
|
|
831
707
|
},
|
|
832
708
|
/** 格式化怪物属性数据 */
|
|
833
709
|
monsterAttributeTextFormat(monster) {
|
|
834
|
-
const { name: name2, type, lv, hp, maxHp, mp, maxMp, atk, def, chr, evasion, hit, ghd, speed, info, pic } = monster;
|
|
710
|
+
const { name: name2, type, lv, hp, maxHp, mp, maxMp, atk, def, chr, evasion, hit, ghd, speed, info, pic, giveProps } = monster;
|
|
711
|
+
const propsList = giveProps.filter((item) => item.lv ? lv >= item.lv : true).map((item) => item.name);
|
|
835
712
|
const attributeText = (pic ? import_koishi.h.image(pic) + "\n" : "") + `Lv.${lv}【${name2}】
|
|
836
713
|
|
|
837
714
|
【怪物类型】${type}
|
|
@@ -843,7 +720,8 @@ var Monster = {
|
|
|
843
720
|
【命中值】${hit}
|
|
844
721
|
【速度值】${speed}
|
|
845
722
|
【暴击率】${(chr / 10).toFixed(1)}%
|
|
846
|
-
【爆伤倍率】${(ghd * 100).toFixed(0)}%` + (
|
|
723
|
+
【爆伤倍率】${(ghd * 100).toFixed(0)}%` + (propsList?.length ? `
|
|
724
|
+
【概率掉落道具】` + propsList.join("、") : "") + (info ? "\n\n" + info : "");
|
|
847
725
|
return attributeText;
|
|
848
726
|
}
|
|
849
727
|
};
|
|
@@ -1090,6 +968,9 @@ var skillFn = {
|
|
|
1090
968
|
mp: 30,
|
|
1091
969
|
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
1092
970
|
const selectGoal = agent.goal;
|
|
971
|
+
if (agent.goal.hp <= 0) {
|
|
972
|
+
return `${getLineupName(agent.self)}已阵亡,无法恢复...`;
|
|
973
|
+
}
|
|
1093
974
|
fn({
|
|
1094
975
|
value: 40,
|
|
1095
976
|
target: [selectGoal],
|
|
@@ -1293,7 +1174,13 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
|
1293
1174
|
const allAgentList = [...currentBattle.goal, ...currentBattle.self].sort((a, b) => b.speed - a.speed);
|
|
1294
1175
|
const msgList = [];
|
|
1295
1176
|
for (const agent of allAgentList) {
|
|
1296
|
-
if (agent.hp <= 0)
|
|
1177
|
+
if (agent.hp <= 0) {
|
|
1178
|
+
if (agent.type == "玩家" && !User.userTempData[agent.userId]?.isDie) {
|
|
1179
|
+
User.userTempData[agent.userId].hp = 0;
|
|
1180
|
+
User.userTempData[agent.userId].isDie = true;
|
|
1181
|
+
}
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1297
1184
|
let lifeGoalList = [];
|
|
1298
1185
|
let lifeSelfList = [];
|
|
1299
1186
|
if (agent.for == "self") {
|
|
@@ -1314,200 +1201,705 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
|
1314
1201
|
} else if (agent.type == "玩家") {
|
|
1315
1202
|
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1316
1203
|
} else {
|
|
1317
|
-
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1204
|
+
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1205
|
+
}
|
|
1206
|
+
const noralAtk = /* @__PURE__ */ __name(() => {
|
|
1207
|
+
const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
|
|
1208
|
+
giveDamage(agent, selectGoal, damageInfo);
|
|
1209
|
+
msgList.push(
|
|
1210
|
+
`${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
|
|
1211
|
+
);
|
|
1212
|
+
}, "noralAtk");
|
|
1213
|
+
if (funType == "普攻") {
|
|
1214
|
+
noralAtk();
|
|
1215
|
+
} else {
|
|
1216
|
+
if (skillFn[atkType]) {
|
|
1217
|
+
if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[atkType].type)) {
|
|
1218
|
+
selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
|
|
1219
|
+
}
|
|
1220
|
+
const selectFn = skillFn[atkType];
|
|
1221
|
+
if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
|
|
1222
|
+
agent.mp -= selectFn.mp;
|
|
1223
|
+
let isNext = false;
|
|
1224
|
+
const fnMsg = selectFn.fn(
|
|
1225
|
+
{ self: agent, goal: selectGoal },
|
|
1226
|
+
{ selfList: lifeSelfList, goalList: lifeGoalList },
|
|
1227
|
+
(val) => {
|
|
1228
|
+
switch (val.type) {
|
|
1229
|
+
case "伤害技" /* 伤害技 */:
|
|
1230
|
+
val.target.map((goal) => {
|
|
1231
|
+
giveDamage(agent, goal, val.damage);
|
|
1232
|
+
});
|
|
1233
|
+
break;
|
|
1234
|
+
case "治疗技" /* 治疗技 */:
|
|
1235
|
+
val.target.map((goal) => {
|
|
1236
|
+
giveCure(goal, val.value);
|
|
1237
|
+
});
|
|
1238
|
+
break;
|
|
1239
|
+
case "释放失败" /* 释放失败 */:
|
|
1240
|
+
val.err && session.send(val.err);
|
|
1241
|
+
default:
|
|
1242
|
+
break;
|
|
1243
|
+
}
|
|
1244
|
+
isNext = val.isNext;
|
|
1245
|
+
}
|
|
1246
|
+
);
|
|
1247
|
+
fnMsg && msgList.push(fnMsg);
|
|
1248
|
+
isNext && noralAtk();
|
|
1249
|
+
} else {
|
|
1250
|
+
await session.send(`MP不足,释放失败!`);
|
|
1251
|
+
noralAtk();
|
|
1252
|
+
}
|
|
1253
|
+
} else {
|
|
1254
|
+
await session.send(`未持有该技能或者该技能不存在,释放失败!`);
|
|
1255
|
+
noralAtk();
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
await session.send(msgList.length ? `战斗记录:
|
|
1260
|
+
` + msgList.join("\n") : "");
|
|
1261
|
+
await session.send(BattleData.battleSituationTextFormat(currentBattle));
|
|
1262
|
+
const result = BattleData.playOver(currentBattle);
|
|
1263
|
+
if (result.over) {
|
|
1264
|
+
await session.send(result.type);
|
|
1265
|
+
await BattleData.settlement(currentBattle, result, session);
|
|
1266
|
+
BattleData.clearBattleData(session);
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
/** 结算奖励 */
|
|
1270
|
+
async settlement(tempData, overInfo, session) {
|
|
1271
|
+
const allList = [...tempData.self, ...tempData.goal].filter((item) => item.type == "玩家");
|
|
1272
|
+
const selfList = tempData.self.filter((item) => item.type == "玩家");
|
|
1273
|
+
const goalList = tempData.goal.filter((item) => item.type == "玩家");
|
|
1274
|
+
const msg = /* @__PURE__ */ __name(async (val) => {
|
|
1275
|
+
const msgTemp = `${val.name}[升级]${val.lv}级!
|
|
1276
|
+
` + (val.atk ? `攻击力↑ ${val.atk}
|
|
1277
|
+
` : "") + (val.def ? `防御力↑ ${val.def}
|
|
1278
|
+
` : "") + (val.maxHp ? `最大血量↑ ${val.maxHp}
|
|
1279
|
+
` : "") + (val.maxMp ? `最大蓝量↑ ${val.maxMp}` : "");
|
|
1280
|
+
await session.send(msgTemp);
|
|
1281
|
+
}, "msg");
|
|
1282
|
+
const aynchronize = /* @__PURE__ */ __name((agent) => {
|
|
1283
|
+
User.userTempData[agent.userId].hp = agent.hp;
|
|
1284
|
+
User.userTempData[agent.userId].mp = agent.mp;
|
|
1285
|
+
}, "aynchronize");
|
|
1286
|
+
if (tempData.isPK) {
|
|
1287
|
+
if (overInfo.win == "self") {
|
|
1288
|
+
await session.send("攻击方获得20EXP、5货币");
|
|
1289
|
+
for (const agent of allList) {
|
|
1290
|
+
aynchronize(agent);
|
|
1291
|
+
if (agent.for == "self") {
|
|
1292
|
+
if (agent.hp <= 0) {
|
|
1293
|
+
User.userTempData[agent.userId].hp = 0;
|
|
1294
|
+
User.userTempData[agent.userId].isDie = true;
|
|
1295
|
+
}
|
|
1296
|
+
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1297
|
+
await User.giveMonetary(agent.userId, 5);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
} else if (overInfo.win == "goal") {
|
|
1301
|
+
await session.send("防御方获得20EXP、5货币");
|
|
1302
|
+
for (const agent of allList) {
|
|
1303
|
+
aynchronize(agent);
|
|
1304
|
+
if (agent.for == "goal") {
|
|
1305
|
+
if (agent.hp <= 0) {
|
|
1306
|
+
User.userTempData[agent.userId].hp = 0;
|
|
1307
|
+
User.userTempData[agent.userId].isDie = true;
|
|
1308
|
+
}
|
|
1309
|
+
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1310
|
+
await User.giveMonetary(agent.userId, 5);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
} else {
|
|
1315
|
+
let val = 0;
|
|
1316
|
+
let monetary = 0;
|
|
1317
|
+
let props = [];
|
|
1318
|
+
const monsterName = tempData.goal.filter((item) => item.type == "怪物").map((i) => ({ name: i.name, lv: i.lv }));
|
|
1319
|
+
monsterName.forEach((item) => {
|
|
1320
|
+
const monster = Monster.monsterTempData[item.name];
|
|
1321
|
+
if (monster) {
|
|
1322
|
+
val += Math.floor(monster.giveExp + monster.giveExp * (item.lv - 1) * 0.2);
|
|
1323
|
+
monetary += Math.floor(monster.giveMonetary + monster.giveExp * (item.lv - 1) * 0.1);
|
|
1324
|
+
monster.giveProps?.forEach((propsItem) => {
|
|
1325
|
+
if (item.lv >= (propsItem.lv || 1) && random(0, 100) < propsItem.radomVal) {
|
|
1326
|
+
props.push({
|
|
1327
|
+
name: propsItem.name,
|
|
1328
|
+
val: propsItem.const ? propsItem.val : random(1, propsItem.val)
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
await session.send(`小队获得${val}EXP、${monetary}货币!`);
|
|
1335
|
+
for (const agent of selfList) {
|
|
1336
|
+
aynchronize(agent);
|
|
1337
|
+
if (overInfo.win == "self") {
|
|
1338
|
+
await User.giveExp(agent.userId, val, async (val2) => await msg(val2));
|
|
1339
|
+
await User.giveMonetary(agent.userId, monetary);
|
|
1340
|
+
props.length && await User.giveProps(agent.userId, props, async (val2) => {
|
|
1341
|
+
const propsDict = {};
|
|
1342
|
+
val2.currentProps.forEach((item) => {
|
|
1343
|
+
if (!propsDict[item.name]) propsDict[item.name] = 1;
|
|
1344
|
+
propsDict[item.name]++;
|
|
1345
|
+
});
|
|
1346
|
+
const msg2 = Object.keys(propsDict).map((item) => {
|
|
1347
|
+
return `${item} ${propsDict[item]}个`;
|
|
1348
|
+
}).join("\n");
|
|
1349
|
+
await session.send(`${agent.name}在战斗中获得:` + msg2);
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
function getLineupName(agent) {
|
|
1357
|
+
return `[${agent.type}]${agent.name}`;
|
|
1358
|
+
}
|
|
1359
|
+
__name(getLineupName, "getLineupName");
|
|
1360
|
+
function initBattleAttribute(data) {
|
|
1361
|
+
if ("playName" in data) {
|
|
1362
|
+
const userData = data;
|
|
1363
|
+
const temp = {
|
|
1364
|
+
userId: userData.userId,
|
|
1365
|
+
name: userData.playName,
|
|
1366
|
+
lv: userData.lv,
|
|
1367
|
+
type: "玩家",
|
|
1368
|
+
hp: userData.hp,
|
|
1369
|
+
maxHp: userData.maxHp,
|
|
1370
|
+
mp: userData.mp,
|
|
1371
|
+
maxMp: userData.maxMp,
|
|
1372
|
+
atk: userData.atk,
|
|
1373
|
+
def: userData.def,
|
|
1374
|
+
chr: userData.chr,
|
|
1375
|
+
ghd: userData.ghd,
|
|
1376
|
+
csr: userData.csr,
|
|
1377
|
+
evasion: userData.evasion,
|
|
1378
|
+
hit: userData.hit,
|
|
1379
|
+
speed: userData.speed,
|
|
1380
|
+
gain: {
|
|
1381
|
+
maxHp: 0,
|
|
1382
|
+
maxMp: 0,
|
|
1383
|
+
atk: 0,
|
|
1384
|
+
def: 0,
|
|
1385
|
+
chr: 0,
|
|
1386
|
+
ghd: 0,
|
|
1387
|
+
evasion: 0,
|
|
1388
|
+
hit: 0,
|
|
1389
|
+
speed: 0
|
|
1390
|
+
},
|
|
1391
|
+
buff: [],
|
|
1392
|
+
fn: []
|
|
1393
|
+
};
|
|
1394
|
+
return temp;
|
|
1395
|
+
} else {
|
|
1396
|
+
const monsterData2 = data;
|
|
1397
|
+
const temp = {
|
|
1398
|
+
name: monsterData2.name,
|
|
1399
|
+
type: "怪物",
|
|
1400
|
+
lv: monsterData2.lv,
|
|
1401
|
+
hp: monsterData2.hp,
|
|
1402
|
+
maxHp: monsterData2.maxHp,
|
|
1403
|
+
mp: monsterData2.mp,
|
|
1404
|
+
maxMp: monsterData2.maxMp,
|
|
1405
|
+
atk: monsterData2.atk,
|
|
1406
|
+
def: monsterData2.def,
|
|
1407
|
+
chr: monsterData2.chr,
|
|
1408
|
+
ghd: monsterData2.ghd,
|
|
1409
|
+
csr: monsterData2.csr,
|
|
1410
|
+
evasion: monsterData2.evasion,
|
|
1411
|
+
hit: monsterData2.hit,
|
|
1412
|
+
speed: monsterData2.speed,
|
|
1413
|
+
gain: {
|
|
1414
|
+
maxHp: 0,
|
|
1415
|
+
maxMp: 0,
|
|
1416
|
+
atk: 0,
|
|
1417
|
+
def: 0,
|
|
1418
|
+
chr: 0,
|
|
1419
|
+
ghd: 0,
|
|
1420
|
+
evasion: 0,
|
|
1421
|
+
hit: 0,
|
|
1422
|
+
speed: 0
|
|
1423
|
+
},
|
|
1424
|
+
buff: [],
|
|
1425
|
+
fn: []
|
|
1426
|
+
};
|
|
1427
|
+
return temp;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
__name(initBattleAttribute, "initBattleAttribute");
|
|
1431
|
+
|
|
1432
|
+
// src/users.ts
|
|
1433
|
+
var UserOccDict = {
|
|
1434
|
+
["剑士" /* 剑士 */]: {
|
|
1435
|
+
info: "擅长近战攻击,拥有强大的属性能力",
|
|
1436
|
+
initStatus: {
|
|
1437
|
+
userId: "",
|
|
1438
|
+
playName: "",
|
|
1439
|
+
type: "剑士" /* 剑士 */,
|
|
1440
|
+
exp: 0,
|
|
1441
|
+
maxExp: 100,
|
|
1442
|
+
lv: 1,
|
|
1443
|
+
hp: 120,
|
|
1444
|
+
maxHp: 120,
|
|
1445
|
+
mp: 80,
|
|
1446
|
+
maxMp: 80,
|
|
1447
|
+
pp: 100,
|
|
1448
|
+
maxPp: 100,
|
|
1449
|
+
atk: 12,
|
|
1450
|
+
def: 5,
|
|
1451
|
+
chr: 50,
|
|
1452
|
+
csr: 0,
|
|
1453
|
+
ghd: 1.2,
|
|
1454
|
+
speed: 5,
|
|
1455
|
+
evasion: 100,
|
|
1456
|
+
hit: 100
|
|
1457
|
+
}
|
|
1458
|
+
},
|
|
1459
|
+
["法师" /* 法师 */]: {
|
|
1460
|
+
info: "精通元素魔法,能够打出爆发伤害",
|
|
1461
|
+
initStatus: {
|
|
1462
|
+
userId: "",
|
|
1463
|
+
playName: "",
|
|
1464
|
+
type: "法师" /* 法师 */,
|
|
1465
|
+
exp: 0,
|
|
1466
|
+
maxExp: 100,
|
|
1467
|
+
lv: 1,
|
|
1468
|
+
hp: 100,
|
|
1469
|
+
maxHp: 100,
|
|
1470
|
+
mp: 100,
|
|
1471
|
+
maxMp: 100,
|
|
1472
|
+
pp: 100,
|
|
1473
|
+
maxPp: 100,
|
|
1474
|
+
atk: 10,
|
|
1475
|
+
def: 2,
|
|
1476
|
+
chr: 50,
|
|
1477
|
+
csr: 0,
|
|
1478
|
+
ghd: 1.2,
|
|
1479
|
+
speed: 5,
|
|
1480
|
+
evasion: 100,
|
|
1481
|
+
hit: 100
|
|
1482
|
+
}
|
|
1483
|
+
},
|
|
1484
|
+
["刺客" /* 刺客 */]: {
|
|
1485
|
+
info: "迅捷攻击,高闪避值的高敏玩家",
|
|
1486
|
+
initStatus: {
|
|
1487
|
+
userId: "",
|
|
1488
|
+
playName: "",
|
|
1489
|
+
type: "刺客" /* 刺客 */,
|
|
1490
|
+
exp: 0,
|
|
1491
|
+
maxExp: 100,
|
|
1492
|
+
lv: 1,
|
|
1493
|
+
hp: 90,
|
|
1494
|
+
maxHp: 90,
|
|
1495
|
+
mp: 70,
|
|
1496
|
+
maxMp: 70,
|
|
1497
|
+
pp: 100,
|
|
1498
|
+
maxPp: 100,
|
|
1499
|
+
atk: 8,
|
|
1500
|
+
def: 2,
|
|
1501
|
+
chr: 80,
|
|
1502
|
+
csr: 0,
|
|
1503
|
+
ghd: 1.3,
|
|
1504
|
+
speed: 6,
|
|
1505
|
+
evasion: 120,
|
|
1506
|
+
hit: 100
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
};
|
|
1510
|
+
var User = {
|
|
1511
|
+
config: {},
|
|
1512
|
+
ctx: {},
|
|
1513
|
+
userTempData: {},
|
|
1514
|
+
async init(config, ctx) {
|
|
1515
|
+
User.config = config;
|
|
1516
|
+
User.ctx = ctx;
|
|
1517
|
+
ctx.model.extend(
|
|
1518
|
+
"smm_gensokyo_user_attribute",
|
|
1519
|
+
{
|
|
1520
|
+
userId: "string",
|
|
1521
|
+
playName: "string",
|
|
1522
|
+
type: "string",
|
|
1523
|
+
exp: "integer",
|
|
1524
|
+
lv: "integer",
|
|
1525
|
+
hp: "integer",
|
|
1526
|
+
mp: "integer",
|
|
1527
|
+
pp: "integer",
|
|
1528
|
+
isDie: "boolean"
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
primary: "userId",
|
|
1532
|
+
autoInc: false
|
|
1533
|
+
}
|
|
1534
|
+
);
|
|
1535
|
+
const userData = await ctx.database.get("smm_gensokyo_user_attribute", {});
|
|
1536
|
+
const temp = {};
|
|
1537
|
+
userData.forEach((item) => {
|
|
1538
|
+
temp[item.userId] = item;
|
|
1539
|
+
});
|
|
1540
|
+
User.userTempData = temp;
|
|
1541
|
+
},
|
|
1542
|
+
/** 获取角色基础属性 */
|
|
1543
|
+
async getUserAttribute(session) {
|
|
1544
|
+
if (!User.userTempData[session.userId]) {
|
|
1545
|
+
await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
return User.getUserAddLvAttribute(session.userId);
|
|
1549
|
+
},
|
|
1550
|
+
/** 获取角色实际等级属性数据 */
|
|
1551
|
+
getUserAddLvAttribute(userId) {
|
|
1552
|
+
const UserDict = User.userTempData[userId];
|
|
1553
|
+
if (!UserDict) return null;
|
|
1554
|
+
const UserData = {
|
|
1555
|
+
...UserOccDict[UserDict.type].initStatus,
|
|
1556
|
+
lv: UserDict.lv,
|
|
1557
|
+
hp: UserDict.hp,
|
|
1558
|
+
mp: UserDict.mp,
|
|
1559
|
+
exp: UserDict.exp,
|
|
1560
|
+
pp: UserDict.pp,
|
|
1561
|
+
playName: UserDict.playName,
|
|
1562
|
+
userId: UserDict.userId
|
|
1563
|
+
};
|
|
1564
|
+
const lv = UserData.lv;
|
|
1565
|
+
const temp = {};
|
|
1566
|
+
const lvScope = Object.keys(userBenchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
1567
|
+
const useBenchmark = userBenchmark[lvScope];
|
|
1568
|
+
Object.keys(UserData).forEach((i) => {
|
|
1569
|
+
temp[i] = UserData[i];
|
|
1570
|
+
if (useBenchmark[i]) {
|
|
1571
|
+
if (i == "maxExp") {
|
|
1572
|
+
temp[i] = Math.floor(100 * useBenchmark[i] * (lv - 1)) || 100;
|
|
1573
|
+
} else {
|
|
1574
|
+
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1578
|
+
return temp;
|
|
1579
|
+
},
|
|
1580
|
+
/** 通过 userId 获取角色属性 */
|
|
1581
|
+
getUserAttributeByUserId(userId) {
|
|
1582
|
+
return User.getUserAddLvAttribute(userId) || null;
|
|
1583
|
+
},
|
|
1584
|
+
/** 创建游戏账号 */
|
|
1585
|
+
async createPlayUser(session) {
|
|
1586
|
+
const [data] = await User.ctx.database.get("smm_gensokyo_user_attribute", { userId: session.userId });
|
|
1587
|
+
if (data) {
|
|
1588
|
+
await session.send("已存在账号,请勿重复创建!");
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
await session.send("请输入自己的游戏昵称:(60s)");
|
|
1592
|
+
const playname = await session.prompt(6e4);
|
|
1593
|
+
if (playname == void 0) return;
|
|
1594
|
+
const [repeat] = await User.ctx.database.get("smm_gensokyo_user_attribute", { playName: playname.trim() });
|
|
1595
|
+
if (repeat) {
|
|
1596
|
+
await session.send("名字重复,请更换一个名字。");
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
if (playname.trim().length > 6 || playname.trim().length < 1) {
|
|
1600
|
+
await session.send("名字长度有问题,要求小于 6个字,大于 1个字");
|
|
1601
|
+
return;
|
|
1602
|
+
}
|
|
1603
|
+
await session.send(`请输入要专职的职业:(60s)
|
|
1604
|
+
${Object.keys(UserOccDict).map((i) => `【${i}】:${UserOccDict[i].info}`).join("\n")}`);
|
|
1605
|
+
let jobType = await session.prompt(6e4);
|
|
1606
|
+
if (jobType == void 0) return;
|
|
1607
|
+
while (!Object.keys(UserOccDict).includes(jobType)) {
|
|
1608
|
+
await session.send("未找到该职业,请重新选择!");
|
|
1609
|
+
jobType = await session.prompt(6e4);
|
|
1610
|
+
}
|
|
1611
|
+
const temp = {
|
|
1612
|
+
userId: session.userId,
|
|
1613
|
+
playName: playname.trim(),
|
|
1614
|
+
type: jobType,
|
|
1615
|
+
hp: UserOccDict[jobType].initStatus.hp,
|
|
1616
|
+
pp: UserOccDict[jobType].initStatus.pp,
|
|
1617
|
+
mp: UserOccDict[jobType].initStatus.mp,
|
|
1618
|
+
lv: 1,
|
|
1619
|
+
exp: 0,
|
|
1620
|
+
isDie: false
|
|
1621
|
+
};
|
|
1622
|
+
User.ctx.database.create("smm_gensokyo_user_attribute", temp);
|
|
1623
|
+
User.userTempData[session.userId] = temp;
|
|
1624
|
+
await Props.initUserPropsData(session.userId);
|
|
1625
|
+
await session.send("创建成功!\n" + User.userAttributeTextFormat(session.userId));
|
|
1626
|
+
},
|
|
1627
|
+
/** 信息格式化 */
|
|
1628
|
+
userAttributeTextFormat(userId) {
|
|
1629
|
+
if (!User.userTempData[userId]) {
|
|
1630
|
+
return "没有找到您的角色信息";
|
|
1631
|
+
}
|
|
1632
|
+
const temp = User.getUserAttributeByUserId(userId);
|
|
1633
|
+
return `昵称:${temp.playName}
|
|
1634
|
+
职位:${temp.type}
|
|
1635
|
+
等级:${temp.lv} (${temp.exp}/${temp.maxExp})
|
|
1636
|
+
-----------------
|
|
1637
|
+
【生命值】${temp.hp}/${temp.maxHp}
|
|
1638
|
+
【魔法值】${temp.mp}/${temp.maxMp}
|
|
1639
|
+
【活力值】${temp.pp}/${temp.maxPp}
|
|
1640
|
+
-----------------
|
|
1641
|
+
【攻击力】${temp.atk} (+0)
|
|
1642
|
+
【防御力】${temp.def} (+0)
|
|
1643
|
+
【速度值】${temp.speed} (+0)
|
|
1644
|
+
【闪避值】${temp.evasion} (+0)
|
|
1645
|
+
【命中率】${(temp.hit / 10 + 100).toFixed(1)}% (+0%)
|
|
1646
|
+
【暴击率】${(temp.chr / 10).toFixed(1)}% (+0%)
|
|
1647
|
+
【暴击伤害】${(temp.ghd * 100).toFixed(1)}% (+0%)` + (temp.csr > 0 ? `
|
|
1648
|
+
【暴击抵抗】${temp.csr}` : "");
|
|
1649
|
+
},
|
|
1650
|
+
/** 写入用户数据到数据库 */
|
|
1651
|
+
async setDatabaseUserAttribute(userId) {
|
|
1652
|
+
const userInfo = User.userTempData[userId];
|
|
1653
|
+
if (!userInfo) return;
|
|
1654
|
+
const temp = {
|
|
1655
|
+
playName: userInfo.playName.trim(),
|
|
1656
|
+
hp: userInfo.hp,
|
|
1657
|
+
pp: userInfo.pp,
|
|
1658
|
+
mp: userInfo.mp,
|
|
1659
|
+
lv: userInfo.lv,
|
|
1660
|
+
exp: userInfo.exp
|
|
1661
|
+
};
|
|
1662
|
+
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
1663
|
+
},
|
|
1664
|
+
/** 给予玩家经验 */
|
|
1665
|
+
async giveExp(userId, value, fn) {
|
|
1666
|
+
const userInfo = User.userTempData[userId];
|
|
1667
|
+
if (!userInfo) return;
|
|
1668
|
+
const beforData = { ...User.getUserAttributeByUserId(userId) };
|
|
1669
|
+
let isUp = false;
|
|
1670
|
+
userInfo.exp += value;
|
|
1671
|
+
while (true) {
|
|
1672
|
+
const { maxExp } = User.getUserAttributeByUserId(userId);
|
|
1673
|
+
if (userInfo.exp < maxExp) break;
|
|
1674
|
+
userInfo.lv += 1;
|
|
1675
|
+
userInfo.exp -= maxExp;
|
|
1676
|
+
isUp = true;
|
|
1677
|
+
}
|
|
1678
|
+
if (isUp) {
|
|
1679
|
+
const afterData = User.getUserAttributeByUserId(userId);
|
|
1680
|
+
const upTemp = {
|
|
1681
|
+
name: afterData.playName,
|
|
1682
|
+
lv: afterData.lv,
|
|
1683
|
+
maxHp: afterData.maxHp - beforData.maxHp,
|
|
1684
|
+
maxMp: afterData.maxMp = beforData.maxMp,
|
|
1685
|
+
atk: afterData.atk - beforData.atk,
|
|
1686
|
+
def: afterData.def - beforData.def
|
|
1687
|
+
};
|
|
1688
|
+
fn && await fn(upTemp);
|
|
1689
|
+
}
|
|
1690
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1691
|
+
},
|
|
1692
|
+
/** 给予玩家死亡 */
|
|
1693
|
+
async giveDie(userId) {
|
|
1694
|
+
const userInfo = User.userTempData[userId];
|
|
1695
|
+
userInfo.hp = 0;
|
|
1696
|
+
userInfo.isDie = true;
|
|
1697
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1698
|
+
},
|
|
1699
|
+
/** 给予玩家复活 */
|
|
1700
|
+
async giveLife(userId, val) {
|
|
1701
|
+
const userInfo = User.userTempData[userId];
|
|
1702
|
+
if (!val) {
|
|
1703
|
+
const { maxHp } = User.getUserAttributeByUserId(userId);
|
|
1704
|
+
userInfo.hp = maxHp;
|
|
1705
|
+
} else {
|
|
1706
|
+
userInfo.hp = val;
|
|
1707
|
+
}
|
|
1708
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1709
|
+
},
|
|
1710
|
+
/** 给予玩家血量或者蓝量 */
|
|
1711
|
+
async giveHPMP(userId, value, fn) {
|
|
1712
|
+
const userInfo = User.userTempData[userId];
|
|
1713
|
+
if (!userInfo) return;
|
|
1714
|
+
if (userInfo.isDie) {
|
|
1715
|
+
fn && await fn({
|
|
1716
|
+
currentHP: 0,
|
|
1717
|
+
currentMP: 0,
|
|
1718
|
+
err: "角色已死亡,无法使用恢复道具。"
|
|
1719
|
+
});
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
if (BattleData.isBattleByUserId(userId)) {
|
|
1723
|
+
const { goal, self } = BattleData.lastPlay[userId];
|
|
1724
|
+
const agentAll = [...goal, ...self];
|
|
1725
|
+
const agent = agentAll.find((item) => item?.userId == userId);
|
|
1726
|
+
if (!agent) return;
|
|
1727
|
+
if (agent.hp + (value.hp || 0) < agent.maxHp) {
|
|
1728
|
+
agent.hp += value.hp || 0;
|
|
1729
|
+
} else {
|
|
1730
|
+
agent.hp = agent.maxHp;
|
|
1318
1731
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
giveDamage(agent, selectGoal, damageInfo);
|
|
1322
|
-
msgList.push(
|
|
1323
|
-
`${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
|
|
1324
|
-
);
|
|
1325
|
-
}, "noralAtk");
|
|
1326
|
-
if (funType == "普攻") {
|
|
1327
|
-
noralAtk();
|
|
1732
|
+
if (agent.mp + (value.mp || 0) < agent.maxMp) {
|
|
1733
|
+
agent.mp += value.mp || 0;
|
|
1328
1734
|
} else {
|
|
1329
|
-
|
|
1330
|
-
if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[atkType].type)) {
|
|
1331
|
-
selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
|
|
1332
|
-
}
|
|
1333
|
-
const selectFn = skillFn[atkType];
|
|
1334
|
-
if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
|
|
1335
|
-
agent.mp -= selectFn.mp;
|
|
1336
|
-
let isNext = false;
|
|
1337
|
-
const fnMsg = selectFn.fn(
|
|
1338
|
-
{ self: agent, goal: selectGoal },
|
|
1339
|
-
{ selfList: lifeSelfList, goalList: lifeGoalList },
|
|
1340
|
-
(val) => {
|
|
1341
|
-
switch (val.type) {
|
|
1342
|
-
case "伤害技" /* 伤害技 */:
|
|
1343
|
-
val.target.map((goal) => {
|
|
1344
|
-
giveDamage(agent, goal, val.damage);
|
|
1345
|
-
});
|
|
1346
|
-
break;
|
|
1347
|
-
case "治疗技" /* 治疗技 */:
|
|
1348
|
-
val.target.map((goal) => {
|
|
1349
|
-
giveCure(goal, val.value);
|
|
1350
|
-
});
|
|
1351
|
-
break;
|
|
1352
|
-
case "释放失败" /* 释放失败 */:
|
|
1353
|
-
val.err && session.send(val.err);
|
|
1354
|
-
default:
|
|
1355
|
-
break;
|
|
1356
|
-
}
|
|
1357
|
-
isNext = val.isNext;
|
|
1358
|
-
}
|
|
1359
|
-
);
|
|
1360
|
-
fnMsg && msgList.push(fnMsg);
|
|
1361
|
-
isNext && noralAtk();
|
|
1362
|
-
} else {
|
|
1363
|
-
await session.send(`MP不足,释放失败!`);
|
|
1364
|
-
noralAtk();
|
|
1365
|
-
}
|
|
1366
|
-
} else {
|
|
1367
|
-
await session.send(`未持有该技能或者该技能不存在,释放失败!`);
|
|
1368
|
-
noralAtk();
|
|
1369
|
-
}
|
|
1735
|
+
agent.mp = agent.maxMp;
|
|
1370
1736
|
}
|
|
1737
|
+
fn && await fn({
|
|
1738
|
+
currentHP: agent.hp,
|
|
1739
|
+
currentMP: agent.mp
|
|
1740
|
+
});
|
|
1741
|
+
return;
|
|
1371
1742
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1743
|
+
const { maxHp, maxMp } = User.getUserAttributeByUserId(userId);
|
|
1744
|
+
if (value.hp && !value.mp && userInfo.hp == maxHp) {
|
|
1745
|
+
fn && await fn({
|
|
1746
|
+
currentHP: userInfo.hp,
|
|
1747
|
+
currentMP: userInfo.mp,
|
|
1748
|
+
err: "当前血量已满,无需回复。"
|
|
1749
|
+
});
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
if (value.mp && !value.hp && userInfo.mp == maxMp) {
|
|
1753
|
+
fn && await fn({
|
|
1754
|
+
currentHP: userInfo.hp,
|
|
1755
|
+
currentMP: userInfo.mp,
|
|
1756
|
+
err: "当前蓝量已满,无需回复。"
|
|
1757
|
+
});
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
if (value.mp && value.hp && userInfo.mp == maxMp && userInfo.hp == maxHp) {
|
|
1761
|
+
fn && await fn({
|
|
1762
|
+
currentHP: userInfo.hp,
|
|
1763
|
+
currentMP: userInfo.mp,
|
|
1764
|
+
err: "当前状态全满,无需回复。"
|
|
1765
|
+
});
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
if (userInfo.hp + (value.hp || 0) < maxHp) {
|
|
1769
|
+
userInfo.hp += value.hp || 0;
|
|
1770
|
+
} else {
|
|
1771
|
+
userInfo.hp = maxHp;
|
|
1772
|
+
}
|
|
1773
|
+
if (userInfo.mp + (value.mp || 0) < maxHp) {
|
|
1774
|
+
userInfo.mp += value.mp || 0;
|
|
1775
|
+
} else {
|
|
1776
|
+
userInfo.mp = maxMp;
|
|
1380
1777
|
}
|
|
1778
|
+
fn && await fn({
|
|
1779
|
+
currentHP: userInfo.hp,
|
|
1780
|
+
currentMP: userInfo.mp
|
|
1781
|
+
});
|
|
1782
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1381
1783
|
},
|
|
1382
|
-
/**
|
|
1383
|
-
async
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1386
|
-
const
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
` + (val.atk ? `攻击力↑ ${val.atk}
|
|
1390
|
-
` : "") + (val.def ? `防御力↑ ${val.def}
|
|
1391
|
-
` : "") + (val.maxHp ? `最大血量↑ ${val.maxHp}
|
|
1392
|
-
` : "") + (val.maxMp ? `最大蓝量↑ ${val.maxMp}` : "");
|
|
1393
|
-
await session.send(msgTemp);
|
|
1394
|
-
}, "msg");
|
|
1395
|
-
const aynchronize = /* @__PURE__ */ __name((agent) => {
|
|
1396
|
-
User.userTempData[agent.userId].hp = agent.hp;
|
|
1397
|
-
User.userTempData[agent.userId].mp = agent.mp;
|
|
1398
|
-
}, "aynchronize");
|
|
1399
|
-
if (tempData.isPK) {
|
|
1400
|
-
if (overInfo.win == "self") {
|
|
1401
|
-
await session.send("攻击方获得20EXP");
|
|
1402
|
-
for (const agent of allList) {
|
|
1403
|
-
aynchronize(agent);
|
|
1404
|
-
if (agent.for == "self") {
|
|
1405
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
} else if (overInfo.win == "goal") {
|
|
1409
|
-
await session.send("防御方获得20EXP");
|
|
1410
|
-
for (const agent of allList) {
|
|
1411
|
-
aynchronize(agent);
|
|
1412
|
-
if (agent.for == "goal") {
|
|
1413
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1784
|
+
/** 给予玩家PP值 */
|
|
1785
|
+
async givePP(userId, value, fn) {
|
|
1786
|
+
const userInfo = User.userTempData[userId];
|
|
1787
|
+
if (!userInfo) return;
|
|
1788
|
+
const { maxPp } = User.getUserAttributeByUserId(userId);
|
|
1789
|
+
if (userInfo.pp + value < maxPp) {
|
|
1790
|
+
userInfo.pp += value;
|
|
1417
1791
|
} else {
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1792
|
+
userInfo.pp = maxPp;
|
|
1793
|
+
}
|
|
1794
|
+
fn && await fn({
|
|
1795
|
+
currentPP: userInfo.pp
|
|
1796
|
+
});
|
|
1797
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1798
|
+
},
|
|
1799
|
+
async lostPP(userId, value, fn) {
|
|
1800
|
+
const userInfo = User.userTempData[userId];
|
|
1801
|
+
if (!userInfo) return;
|
|
1802
|
+
if (userInfo.pp - value < 0) {
|
|
1803
|
+
fn && await fn({
|
|
1804
|
+
currentPP: userInfo.pp,
|
|
1805
|
+
err: "PP值不够,消耗失败!"
|
|
1425
1806
|
});
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
userInfo.pp -= value;
|
|
1810
|
+
fn && await fn({
|
|
1811
|
+
currentPP: userInfo.pp
|
|
1812
|
+
});
|
|
1813
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1814
|
+
},
|
|
1815
|
+
/** 给予玩家货币 */
|
|
1816
|
+
async giveMonetary(userId, val, fn) {
|
|
1817
|
+
const [bindData] = await User.ctx.database.get("binding", { pid: userId });
|
|
1818
|
+
if (bindData && val) {
|
|
1819
|
+
const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
|
|
1820
|
+
await User.ctx.monetary.gain(bindData.aid, val);
|
|
1821
|
+
fn && await fn({ val, currentVal: currentM.value += val });
|
|
1822
|
+
}
|
|
1823
|
+
},
|
|
1824
|
+
/** 收取玩家货币 */
|
|
1825
|
+
async lostMonetary(userId, val, fn) {
|
|
1826
|
+
const [bindData] = await User.ctx.database.get("binding", { pid: userId });
|
|
1827
|
+
if (bindData && val) {
|
|
1828
|
+
const [currentM] = await User.ctx.database.get("monetary", { uid: bindData.aid });
|
|
1829
|
+
if (currentM.value - val < 0) {
|
|
1830
|
+
fn && await fn({
|
|
1831
|
+
val: Math.abs(val),
|
|
1832
|
+
currentVal: currentM.value,
|
|
1833
|
+
err: "余额不足!"
|
|
1834
|
+
});
|
|
1835
|
+
return;
|
|
1432
1836
|
}
|
|
1837
|
+
await User.ctx.monetary.cost(bindData.aid, val);
|
|
1838
|
+
fn && await fn({
|
|
1839
|
+
val: Math.abs(val),
|
|
1840
|
+
currentVal: currentM.value - val
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
},
|
|
1844
|
+
/** 给予玩家指定道具 */
|
|
1845
|
+
async giveProps(userId, props, fn) {
|
|
1846
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
1847
|
+
if (!userProps) return;
|
|
1848
|
+
const upProps = [];
|
|
1849
|
+
for (const item of props) {
|
|
1850
|
+
const propsItem = propsData[item.name];
|
|
1851
|
+
if (!propsItem) continue;
|
|
1852
|
+
userProps[item.name] = {
|
|
1853
|
+
name: propsItem.name,
|
|
1854
|
+
type: propsItem.type,
|
|
1855
|
+
value: 0
|
|
1856
|
+
};
|
|
1857
|
+
userProps[item.name].value += item.val || 1;
|
|
1858
|
+
upProps.push({ name: item.name, val: userProps[item.name].value });
|
|
1859
|
+
}
|
|
1860
|
+
fn && await fn({
|
|
1861
|
+
currentProps: upProps
|
|
1862
|
+
});
|
|
1863
|
+
await Props.setDatabasePropsData(userId);
|
|
1864
|
+
},
|
|
1865
|
+
/** 去除玩家指定道具 */
|
|
1866
|
+
async loseProps(userId, props, fn) {
|
|
1867
|
+
const userProps = Props.userPorpsTemp[userId];
|
|
1868
|
+
const propsItem = propsData[props.name];
|
|
1869
|
+
if (!userProps) return;
|
|
1870
|
+
if (!propsItem) {
|
|
1871
|
+
fn && await fn({
|
|
1872
|
+
currentProps: { name: props.name, val: 0 },
|
|
1873
|
+
err: "该道具信息不存在!"
|
|
1874
|
+
});
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
if (!userProps[props.name]) {
|
|
1878
|
+
userProps[props.name] = {
|
|
1879
|
+
name: propsItem.name,
|
|
1880
|
+
type: propsItem.type,
|
|
1881
|
+
value: 0
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
if (userProps[props.name].value - (props.val || 1) < 0) {
|
|
1885
|
+
fn && await fn({
|
|
1886
|
+
currentProps: { name: props.name, val: userProps[props.name].value },
|
|
1887
|
+
err: `道具数量不足!剩余${userProps[props.name].value}个。`
|
|
1888
|
+
});
|
|
1889
|
+
return;
|
|
1433
1890
|
}
|
|
1891
|
+
userProps[props.name].value -= props.val || 1;
|
|
1892
|
+
if (userProps[props.name].value == 0) delete userProps[props.name];
|
|
1893
|
+
fn && await fn({
|
|
1894
|
+
currentProps: { name: props.name, val: userProps[props.name]?.value || 0 }
|
|
1895
|
+
});
|
|
1896
|
+
await Props.setDatabasePropsData(userId);
|
|
1897
|
+
},
|
|
1898
|
+
/** 目标是否死亡 */
|
|
1899
|
+
isDie(userId) {
|
|
1900
|
+
return User.userTempData[userId]?.isDie;
|
|
1434
1901
|
}
|
|
1435
1902
|
};
|
|
1436
|
-
function getLineupName(agent) {
|
|
1437
|
-
return `[${agent.type}]${agent.name}`;
|
|
1438
|
-
}
|
|
1439
|
-
__name(getLineupName, "getLineupName");
|
|
1440
|
-
function initBattleAttribute(data) {
|
|
1441
|
-
if ("playName" in data) {
|
|
1442
|
-
const userData = data;
|
|
1443
|
-
const temp = {
|
|
1444
|
-
userId: userData.userId,
|
|
1445
|
-
name: userData.playName,
|
|
1446
|
-
lv: userData.lv,
|
|
1447
|
-
type: "玩家",
|
|
1448
|
-
hp: userData.hp,
|
|
1449
|
-
maxHp: userData.maxHp,
|
|
1450
|
-
mp: userData.mp,
|
|
1451
|
-
maxMp: userData.maxMp,
|
|
1452
|
-
atk: userData.atk,
|
|
1453
|
-
def: userData.def,
|
|
1454
|
-
chr: userData.chr,
|
|
1455
|
-
ghd: userData.ghd,
|
|
1456
|
-
csr: userData.csr,
|
|
1457
|
-
evasion: userData.evasion,
|
|
1458
|
-
hit: userData.hit,
|
|
1459
|
-
speed: userData.speed,
|
|
1460
|
-
gain: {
|
|
1461
|
-
maxHp: 0,
|
|
1462
|
-
maxMp: 0,
|
|
1463
|
-
atk: 0,
|
|
1464
|
-
def: 0,
|
|
1465
|
-
chr: 0,
|
|
1466
|
-
ghd: 0,
|
|
1467
|
-
evasion: 0,
|
|
1468
|
-
hit: 0,
|
|
1469
|
-
speed: 0
|
|
1470
|
-
},
|
|
1471
|
-
buff: [],
|
|
1472
|
-
fn: []
|
|
1473
|
-
};
|
|
1474
|
-
return temp;
|
|
1475
|
-
} else {
|
|
1476
|
-
const monsterData2 = data;
|
|
1477
|
-
const temp = {
|
|
1478
|
-
name: monsterData2.name,
|
|
1479
|
-
type: "怪物",
|
|
1480
|
-
lv: monsterData2.lv,
|
|
1481
|
-
hp: monsterData2.hp,
|
|
1482
|
-
maxHp: monsterData2.maxHp,
|
|
1483
|
-
mp: monsterData2.mp,
|
|
1484
|
-
maxMp: monsterData2.maxMp,
|
|
1485
|
-
atk: monsterData2.atk,
|
|
1486
|
-
def: monsterData2.def,
|
|
1487
|
-
chr: monsterData2.chr,
|
|
1488
|
-
ghd: monsterData2.ghd,
|
|
1489
|
-
csr: monsterData2.csr,
|
|
1490
|
-
evasion: monsterData2.evasion,
|
|
1491
|
-
hit: monsterData2.hit,
|
|
1492
|
-
speed: monsterData2.speed,
|
|
1493
|
-
gain: {
|
|
1494
|
-
maxHp: 0,
|
|
1495
|
-
maxMp: 0,
|
|
1496
|
-
atk: 0,
|
|
1497
|
-
def: 0,
|
|
1498
|
-
chr: 0,
|
|
1499
|
-
ghd: 0,
|
|
1500
|
-
evasion: 0,
|
|
1501
|
-
hit: 0,
|
|
1502
|
-
speed: 0
|
|
1503
|
-
},
|
|
1504
|
-
buff: [],
|
|
1505
|
-
fn: []
|
|
1506
|
-
};
|
|
1507
|
-
return temp;
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
__name(initBattleAttribute, "initBattleAttribute");
|
|
1511
1903
|
|
|
1512
1904
|
// src/index.ts
|
|
1513
1905
|
var name = "smmcat-gensokyo";
|
|
@@ -1520,6 +1912,7 @@ function apply(ctx, config) {
|
|
|
1520
1912
|
GensokyoMap.init(config, ctx);
|
|
1521
1913
|
User.init(config, ctx);
|
|
1522
1914
|
Monster.init(config, ctx);
|
|
1915
|
+
Props.init(config, ctx);
|
|
1523
1916
|
});
|
|
1524
1917
|
ctx.command("幻想乡");
|
|
1525
1918
|
ctx.command("幻想乡/移动.上").action(async ({ session }) => {
|
|
@@ -1628,9 +2021,25 @@ function apply(ctx, config) {
|
|
|
1628
2021
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, query));
|
|
1629
2022
|
});
|
|
1630
2023
|
ctx.command("幻想乡/个人属性").action(async ({ session }) => {
|
|
2024
|
+
const userData = await User.getUserAttribute(session);
|
|
2025
|
+
if (!userData) return;
|
|
2026
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
1631
2027
|
return `您的属性如下:
|
|
1632
2028
|
` + User.userAttributeTextFormat(session.userId);
|
|
1633
2029
|
});
|
|
2030
|
+
ctx.command("幻想乡/个人道具").action(async ({ session }) => {
|
|
2031
|
+
const userData = await User.getUserAttribute(session);
|
|
2032
|
+
if (!userData) return;
|
|
2033
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2034
|
+
return await Props.getPropsDataByUserId(session.userId);
|
|
2035
|
+
});
|
|
2036
|
+
ctx.command("幻想乡/个人信息").userFields(["id"]).action(async ({ session }) => {
|
|
2037
|
+
const userData = await User.getUserAttribute(session);
|
|
2038
|
+
if (!userData) return;
|
|
2039
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2040
|
+
const [data] = await ctx.database.get("monetary", { uid: session.user.id });
|
|
2041
|
+
return `[${User.userTempData[session.userId].playName}]:您当前货币为:${data?.value || 0}个`;
|
|
2042
|
+
});
|
|
1634
2043
|
ctx.command("幻想乡/开始注册").action(async ({ session }) => {
|
|
1635
2044
|
await User.createPlayUser(session);
|
|
1636
2045
|
});
|
|
@@ -1699,6 +2108,15 @@ function apply(ctx, config) {
|
|
|
1699
2108
|
await BattleData.createBattleByUser(session, [{ userId: exist.userId }]);
|
|
1700
2109
|
}
|
|
1701
2110
|
});
|
|
2111
|
+
ctx.command("幻想乡/道具使用 <props>").action(async ({ session }, props) => {
|
|
2112
|
+
const userData = await User.getUserAttribute(session);
|
|
2113
|
+
if (!userData) return;
|
|
2114
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
2115
|
+
if (!props) {
|
|
2116
|
+
return `未选择道具使用,请选择道具,例如:/道具使用 红药`;
|
|
2117
|
+
}
|
|
2118
|
+
await Props.userProps(session, props);
|
|
2119
|
+
});
|
|
1702
2120
|
ctx.command("幻想乡/技能查询 <goal>").action(async ({ session }, goal) => {
|
|
1703
2121
|
if (!goal) return `请输入技能名,例如 /技能查询 重砍`;
|
|
1704
2122
|
if (!skillFn[goal]) return `没有存在 ${goal} 技能!`;
|
|
@@ -1722,6 +2140,7 @@ function apply(ctx, config) {
|
|
|
1722
2140
|
console.log(maxMp);
|
|
1723
2141
|
User.userTempData[session.userId].hp = maxHp;
|
|
1724
2142
|
User.userTempData[session.userId].mp = maxMp;
|
|
2143
|
+
User.userTempData[session.userId].isDie = false;
|
|
1725
2144
|
console.log(User.userTempData[session.userId]);
|
|
1726
2145
|
await User.setDatabaseUserAttribute(session.userId);
|
|
1727
2146
|
return playName + `通过补给,目前已恢复HP和MP`;
|