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/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/users.ts
365
- var UserOccDict = {
366
- ["剑士" /* 剑士 */]: {
367
- info: "擅长近战攻击,拥有强大的属性能力",
368
- initStatus: {
369
- userId: "",
370
- playName: "",
371
- type: "剑士" /* 剑士 */,
372
- exp: 0,
373
- maxExp: 100,
374
- lv: 1,
375
- hp: 120,
376
- maxHp: 120,
377
- mp: 80,
378
- maxMp: 80,
379
- pp: 100,
380
- maxPp: 100,
381
- atk: 12,
382
- def: 5,
383
- chr: 50,
384
- csr: 0,
385
- ghd: 1.2,
386
- speed: 5,
387
- evasion: 100,
388
- hit: 100
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
- info: "精通元素魔法,能够打出爆发伤害",
393
- initStatus: {
394
- userId: "",
395
- playName: "",
396
- type: "法师" /* 法师 */,
397
- exp: 0,
398
- maxExp: 100,
399
- lv: 1,
400
- hp: 100,
401
- maxHp: 100,
402
- mp: 100,
403
- maxMp: 100,
404
- pp: 100,
405
- maxPp: 100,
406
- atk: 10,
407
- def: 2,
408
- chr: 50,
409
- csr: 0,
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
- info: "迅捷攻击,高闪避值的高敏玩家",
418
- initStatus: {
419
- userId: "",
420
- playName: "",
421
- type: "刺客" /* 刺客 */,
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
- var User = {
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
- userTempData: {},
650
+ monsterTempData: {},
446
651
  async init(config, ctx) {
447
- User.config = config;
448
- User.ctx = ctx;
652
+ Monster.config = config;
653
+ Monster.ctx = ctx;
449
654
  ctx.model.extend(
450
- "smm_gensokyo_user_attribute",
655
+ "smm_gensokyo_monster_attribute",
451
656
  {
452
- userId: "string",
453
- playName: "string",
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
- pp: "integer"
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: "userId",
674
+ primary: "id",
463
675
  autoInc: false
464
676
  }
465
677
  );
466
- const userData = await ctx.database.get("smm_gensokyo_user_attribute", {});
467
- const temp = {};
468
- userData.forEach((item) => {
469
- temp[item.userId] = item;
470
- });
471
- User.userTempData = temp;
472
- },
473
- /** 获取角色基础属性 */
474
- async getUserAttribute(session) {
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(benchmark).reverse().find((item) => Number(item) < lv) || 10;
822
- const useBenchmark = benchmark[lvScope];
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)}%` + (info ? "\n\n" + info : "");
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) continue;
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
- const noralAtk = /* @__PURE__ */ __name(() => {
1320
- const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
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
- if (skillFn[atkType]) {
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
- await session.send(msgList.length ? `战斗记录:
1373
- ` + msgList.join("\n") : "");
1374
- await session.send(BattleData.battleSituationTextFormat(currentBattle));
1375
- const result = BattleData.playOver(currentBattle);
1376
- if (result.over) {
1377
- await session.send(result.type);
1378
- await BattleData.settlement(currentBattle, result, session);
1379
- BattleData.clearBattleData(session);
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 settlement(tempData, overInfo, session) {
1384
- const allList = [...tempData.self, ...tempData.goal].filter((item) => item.type == "玩家");
1385
- const selfList = tempData.self.filter((item) => item.type == "玩家");
1386
- const goalList = tempData.goal.filter((item) => item.type == "玩家");
1387
- const msg = /* @__PURE__ */ __name(async (val) => {
1388
- const msgTemp = `${val.name}[升级]${val.lv}级!
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
- let val = 0;
1419
- const monsterName = tempData.goal.filter((item) => item.type == "怪物").map((i) => ({ name: i.name, lv: i.lv }));
1420
- monsterName.forEach((item) => {
1421
- const monster = Monster.monsterTempData[item.name];
1422
- if (monster) {
1423
- val += Math.floor(monster.giveExp + monster.giveExp * (item.lv - 1) * 0.2);
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
- for (const agent of selfList) {
1427
- aynchronize(agent);
1428
- if (overInfo.win == "self") {
1429
- await session.send(`小队获得${val}EXP`);
1430
- await User.giveExp(agent.userId, val, async (val2) => await msg(val2));
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`;