koishi-plugin-smmcat-gensokyo 0.0.14 → 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/initMonster.d.ts +13 -0
- package/lib/data/initProps.d.ts +3 -2
- package/lib/index.js +1334 -1078
- package/lib/props.d.ts +4 -1
- package/lib/skillFn.d.ts +5 -1
- package/lib/users.d.ts +30 -8
- 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: "绿野平原六"
|
|
@@ -442,6 +443,58 @@ var userBenchmark = {
|
|
|
442
443
|
}
|
|
443
444
|
};
|
|
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
|
+
|
|
445
498
|
// src/props.ts
|
|
446
499
|
var Props = {
|
|
447
500
|
config: {},
|
|
@@ -475,1196 +528,1378 @@ var Props = {
|
|
|
475
528
|
await Props.ctx.database.create("smm_gensokyo_user_props", temp);
|
|
476
529
|
}
|
|
477
530
|
},
|
|
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
|
+
},
|
|
478
542
|
/** 更新本地数据库对应数据 */
|
|
479
543
|
async setDatabasePropsData(userId) {
|
|
480
|
-
const
|
|
481
|
-
if (
|
|
544
|
+
const propsData2 = Props.userPorpsTemp[userId];
|
|
545
|
+
if (propsData2) {
|
|
482
546
|
const temp = {
|
|
483
|
-
props:
|
|
547
|
+
props: propsData2
|
|
484
548
|
};
|
|
485
549
|
await Props.ctx.database.set("smm_gensokyo_user_props", { userId }, temp);
|
|
486
550
|
}
|
|
551
|
+
},
|
|
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;
|
|
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
|
+
});
|
|
487
566
|
}
|
|
488
567
|
};
|
|
489
568
|
|
|
490
|
-
// src/
|
|
491
|
-
var
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
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
|
+
]
|
|
516
596
|
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
hit: 100
|
|
540
|
-
}
|
|
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
|
+
]
|
|
541
619
|
},
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
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
|
+
]
|
|
566
643
|
}
|
|
567
644
|
};
|
|
568
|
-
|
|
645
|
+
|
|
646
|
+
// src/monster.ts
|
|
647
|
+
var Monster = {
|
|
569
648
|
config: {},
|
|
570
649
|
ctx: {},
|
|
571
|
-
|
|
650
|
+
monsterTempData: {},
|
|
572
651
|
async init(config, ctx) {
|
|
573
|
-
|
|
574
|
-
|
|
652
|
+
Monster.config = config;
|
|
653
|
+
Monster.ctx = ctx;
|
|
575
654
|
ctx.model.extend(
|
|
576
|
-
"
|
|
655
|
+
"smm_gensokyo_monster_attribute",
|
|
577
656
|
{
|
|
578
|
-
|
|
579
|
-
|
|
657
|
+
id: "integer",
|
|
658
|
+
name: "string",
|
|
659
|
+
info: "string",
|
|
580
660
|
type: "string",
|
|
581
|
-
exp: "integer",
|
|
582
|
-
lv: "integer",
|
|
583
661
|
hp: "integer",
|
|
662
|
+
maxHp: "integer",
|
|
584
663
|
mp: "integer",
|
|
585
|
-
|
|
586
|
-
|
|
664
|
+
maxMp: "integer",
|
|
665
|
+
atk: "integer",
|
|
666
|
+
def: "integer",
|
|
667
|
+
chr: "integer",
|
|
668
|
+
evasion: "integer",
|
|
669
|
+
hit: "integer",
|
|
670
|
+
ghd: "integer",
|
|
671
|
+
speed: "integer"
|
|
587
672
|
},
|
|
588
673
|
{
|
|
589
|
-
primary: "
|
|
674
|
+
primary: "id",
|
|
590
675
|
autoInc: false
|
|
591
676
|
}
|
|
592
677
|
);
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
if (!User.userTempData[session.userId]) {
|
|
603
|
-
await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
|
|
604
|
-
return null;
|
|
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;
|
|
605
687
|
}
|
|
606
|
-
return User.getUserAddLvAttribute(session.userId);
|
|
607
688
|
},
|
|
608
|
-
/**
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
};
|
|
622
|
-
const lv = UserData.lv;
|
|
623
|
-
const temp = {};
|
|
624
|
-
const lvScope = Object.keys(userBenchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
625
|
-
const useBenchmark = userBenchmark[lvScope];
|
|
626
|
-
Object.keys(UserData).forEach((i) => {
|
|
627
|
-
temp[i] = UserData[i];
|
|
689
|
+
/** 赋予原始的怪物数据 */
|
|
690
|
+
_createInitMonsterData() {
|
|
691
|
+
return monsterData;
|
|
692
|
+
},
|
|
693
|
+
getMonsterAttributeData(monsterName, lv) {
|
|
694
|
+
const monster = Monster.monsterTempData[monsterName];
|
|
695
|
+
if (!monster) return null;
|
|
696
|
+
const temp = { lv };
|
|
697
|
+
const lvScope = Object.keys(monsterBenchmark).reverse().find((item) => Number(item) < lv) || 10;
|
|
698
|
+
const useBenchmark = monsterBenchmark[lvScope];
|
|
699
|
+
console.log(useBenchmark);
|
|
700
|
+
Object.keys(monster).forEach((i) => {
|
|
701
|
+
temp[i] = monster[i];
|
|
628
702
|
if (useBenchmark[i]) {
|
|
629
|
-
|
|
630
|
-
temp[i] = Math.floor(100 * useBenchmark[i] * (lv - 1)) || 100;
|
|
631
|
-
} else {
|
|
632
|
-
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
633
|
-
}
|
|
703
|
+
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
634
704
|
}
|
|
635
705
|
});
|
|
636
706
|
return temp;
|
|
637
707
|
},
|
|
638
|
-
/**
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
708
|
+
/** 格式化怪物属性数据 */
|
|
709
|
+
monsterAttributeTextFormat(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);
|
|
712
|
+
const attributeText = (pic ? import_koishi.h.image(pic) + "\n" : "") + `Lv.${lv}【${name2}】
|
|
713
|
+
|
|
714
|
+
【怪物类型】${type}
|
|
715
|
+
【生命值】${hp}/${maxHp}
|
|
716
|
+
【魔法值】${mp}/${maxMp}
|
|
717
|
+
【攻击力】${atk}
|
|
718
|
+
【防御力】${def}
|
|
719
|
+
【闪避值】${evasion}
|
|
720
|
+
【命中值】${hit}
|
|
721
|
+
【速度值】${speed}
|
|
722
|
+
【暴击率】${(chr / 10).toFixed(1)}%
|
|
723
|
+
【爆伤倍率】${(ghd * 100).toFixed(0)}%` + (propsList?.length ? `
|
|
724
|
+
【概率掉落道具】` + propsList.join("、") : "") + (info ? "\n\n" + info : "");
|
|
725
|
+
return attributeText;
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
// src/utlis.ts
|
|
730
|
+
var random = /* @__PURE__ */ __name((min, max) => {
|
|
731
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
732
|
+
}, "random");
|
|
733
|
+
var generateHealthDisplay = /* @__PURE__ */ __name((current, total) => {
|
|
734
|
+
const ratio = current / total;
|
|
735
|
+
const displayLength = 10;
|
|
736
|
+
const filledLength = Math.floor(ratio * displayLength);
|
|
737
|
+
const unfilledLength = displayLength - filledLength;
|
|
738
|
+
const filled = "■".repeat(filledLength);
|
|
739
|
+
const unfilled = "□".repeat(unfilledLength);
|
|
740
|
+
return filled + unfilled;
|
|
741
|
+
}, "generateHealthDisplay");
|
|
742
|
+
|
|
743
|
+
// src/damage.ts
|
|
744
|
+
var Damage = class {
|
|
745
|
+
static {
|
|
746
|
+
__name(this, "Damage");
|
|
747
|
+
}
|
|
748
|
+
config;
|
|
749
|
+
constructor(agent, realHarm = false) {
|
|
750
|
+
this.config = {
|
|
751
|
+
agent: { self: { ...agent.self }, goal: { ...agent.goal } },
|
|
752
|
+
harm: 0,
|
|
753
|
+
default_harm: 0,
|
|
754
|
+
isRealHarm: realHarm,
|
|
755
|
+
isEvasion: false,
|
|
756
|
+
isCsp: false,
|
|
757
|
+
isBadDef: false
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
/** 伤害判定前 */
|
|
761
|
+
before(fn) {
|
|
762
|
+
this.config.default_harm = this.config.agent.self.atk + this.config.agent.self.gain.atk;
|
|
763
|
+
fn && fn(this.config);
|
|
764
|
+
return this;
|
|
765
|
+
}
|
|
766
|
+
/** 真实伤害判定 */
|
|
767
|
+
beforRealHarm(fn) {
|
|
768
|
+
fn && fn(this.config);
|
|
769
|
+
if (this.config.isRealHarm) {
|
|
770
|
+
this.config.harm = this.config.default_harm;
|
|
648
771
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
772
|
+
return this;
|
|
773
|
+
}
|
|
774
|
+
/** 是否闪避判定 */
|
|
775
|
+
evasion(fn) {
|
|
776
|
+
const { self, goal } = this.config.agent;
|
|
777
|
+
if (this.config.isRealHarm) return this;
|
|
778
|
+
const lvSup = /* @__PURE__ */ __name(() => Math.floor((goal.lv - self.lv) / 5) * 20, "lvSup");
|
|
779
|
+
const evaVal = Math.min(95, (goal.evasion + goal.gain.evasion - self.hit + lvSup()) / 10);
|
|
780
|
+
if (random(0, 100) <= evaVal) {
|
|
781
|
+
this.config.isEvasion = true;
|
|
782
|
+
fn && fn(this.config);
|
|
783
|
+
return this;
|
|
656
784
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
785
|
+
fn && fn(this.config);
|
|
786
|
+
return this;
|
|
787
|
+
}
|
|
788
|
+
/** 是否暴击判定 */
|
|
789
|
+
csp(fn) {
|
|
790
|
+
const { self, goal } = this.config.agent;
|
|
791
|
+
if (this.config.isRealHarm) return this;
|
|
792
|
+
if (this.config.isEvasion) return this;
|
|
793
|
+
const cspVal = (self.chr + self.gain.chr - goal.csr) / 10;
|
|
794
|
+
if (random(0, 100) <= cspVal) {
|
|
795
|
+
this.config.isCsp = true;
|
|
796
|
+
this.config.harm = Math.floor(this.config.default_harm * (self.ghd + self.gain.ghd));
|
|
797
|
+
fn && fn(this.config);
|
|
798
|
+
return this;
|
|
660
799
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
800
|
+
this.config.harm = this.config.default_harm;
|
|
801
|
+
fn && fn(this.config);
|
|
802
|
+
return this;
|
|
803
|
+
}
|
|
804
|
+
/** 防御结算 */
|
|
805
|
+
beforDef(fn) {
|
|
806
|
+
const { goal } = this.config.agent;
|
|
807
|
+
if (this.config.isRealHarm) return this;
|
|
808
|
+
if (this.config.isEvasion) return this;
|
|
809
|
+
const dpVal = goal.def + goal.gain.def;
|
|
810
|
+
fn && fn(this.config);
|
|
811
|
+
if (this.config.harm - dpVal > 0) {
|
|
812
|
+
this.config.harm -= dpVal;
|
|
813
|
+
} else {
|
|
814
|
+
this.config.isBadDef = true;
|
|
815
|
+
this.config.harm = 1;
|
|
668
816
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
817
|
+
return this;
|
|
818
|
+
}
|
|
819
|
+
result(fn) {
|
|
820
|
+
this.before((val) => {
|
|
821
|
+
fn?.before && fn.before(val);
|
|
822
|
+
}).beforRealHarm((val) => {
|
|
823
|
+
fn?.beforRealHarm && fn.beforRealHarm(val);
|
|
824
|
+
}).evasion((val) => {
|
|
825
|
+
fn?.evasion && fn.evasion(val);
|
|
826
|
+
}).csp((val) => {
|
|
827
|
+
fn?.csp && fn.csp(val);
|
|
828
|
+
}).beforDef((val) => {
|
|
829
|
+
fn?.beforDef && fn.beforDef(val);
|
|
830
|
+
});
|
|
831
|
+
return this.config;
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
function giveDamage(self, goal, damage) {
|
|
835
|
+
if (goal.hp - damage.harm > 0) {
|
|
836
|
+
goal.hp -= damage.harm;
|
|
837
|
+
return damage.harm;
|
|
838
|
+
} else {
|
|
839
|
+
const lostHp = goal.hp;
|
|
840
|
+
goal.hp = 0;
|
|
841
|
+
return lostHp;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
__name(giveDamage, "giveDamage");
|
|
845
|
+
function giveCure(goal, val) {
|
|
846
|
+
const upVal = goal.hp + val;
|
|
847
|
+
if (upVal < goal.maxHp + goal.gain.maxHp) {
|
|
848
|
+
goal.hp = upVal;
|
|
849
|
+
return val;
|
|
850
|
+
} else {
|
|
851
|
+
const abHp = goal.maxHp + goal.gain.maxHp - goal.hp;
|
|
852
|
+
goal.hp += abHp;
|
|
853
|
+
return abHp;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
__name(giveCure, "giveCure");
|
|
857
|
+
function moreDamageInfo(damage) {
|
|
858
|
+
return (damage.isCsp ? `(暴击!)` : "") + (damage.isEvasion ? `(闪避成功!)` : "") + (damage.isBadDef ? `(未破防!)` : "");
|
|
859
|
+
}
|
|
860
|
+
__name(moreDamageInfo, "moreDamageInfo");
|
|
861
|
+
|
|
862
|
+
// src/skillFn.ts
|
|
863
|
+
var skillFn = {
|
|
864
|
+
"重砍": {
|
|
865
|
+
name: "重砍",
|
|
866
|
+
type: "伤害技" /* 伤害技 */,
|
|
867
|
+
info: "[伤害技]消耗10MP,对敌方一个单位造成基于攻击力1.2倍伤害。该次伤害无视敌方30%防御!(最低无视1防御)",
|
|
868
|
+
lv: 3,
|
|
869
|
+
mp: 10,
|
|
870
|
+
feature: ["剑士" /* 剑士 */],
|
|
871
|
+
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
872
|
+
const damageData = new Damage(agent).result({
|
|
873
|
+
before: /* @__PURE__ */ __name((val) => {
|
|
874
|
+
val.default_harm += Math.floor(val.default_harm * 0.2);
|
|
875
|
+
val.agent.goal.def -= Math.floor(val.agent.goal.def * 0.3) || 1;
|
|
876
|
+
}, "before")
|
|
877
|
+
});
|
|
878
|
+
fn({
|
|
879
|
+
damage: damageData,
|
|
880
|
+
type: this.type,
|
|
881
|
+
target: [agent.goal],
|
|
882
|
+
isNext: false
|
|
883
|
+
});
|
|
884
|
+
return `${getLineupName(agent.self)} 释放重砍,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
885
|
+
}, "fn")
|
|
684
886
|
},
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
887
|
+
"突刺": {
|
|
888
|
+
name: "突刺",
|
|
889
|
+
type: "伤害技" /* 伤害技 */,
|
|
890
|
+
info: "[伤害技]消耗10MP,对敌方一个单位造成基于攻击力1.2倍伤害,该伤害无视敌方闪避10%",
|
|
891
|
+
lv: 3,
|
|
892
|
+
mp: 10,
|
|
893
|
+
feature: ["刺客" /* 刺客 */],
|
|
894
|
+
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
895
|
+
const damageData = new Damage(agent).result({
|
|
896
|
+
before: /* @__PURE__ */ __name((val) => {
|
|
897
|
+
val.default_harm += Math.floor(val.default_harm * 0.2);
|
|
898
|
+
val.agent.goal.evasion -= Math.floor((val.agent.goal.evasion + val.agent.goal.gain.evasion) * 0.1);
|
|
899
|
+
}, "before")
|
|
900
|
+
});
|
|
901
|
+
fn({
|
|
902
|
+
damage: damageData,
|
|
903
|
+
type: this.type,
|
|
904
|
+
target: [agent.goal],
|
|
905
|
+
isNext: false
|
|
906
|
+
});
|
|
907
|
+
return `${getLineupName(agent.self)} 释放突刺,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
908
|
+
}, "fn")
|
|
707
909
|
},
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
910
|
+
"水炮": {
|
|
911
|
+
name: "水炮",
|
|
912
|
+
type: "伤害技" /* 伤害技 */,
|
|
913
|
+
info: "[伤害技]消耗10MP,通过凝集魔力对敌方造成基于攻击力1.2倍伤害,该伤害基于当前剩余魔法值10%额外叠加伤害。",
|
|
914
|
+
lv: 3,
|
|
915
|
+
mp: 10,
|
|
916
|
+
feature: ["法师" /* 法师 */],
|
|
917
|
+
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
918
|
+
const damageData = new Damage(agent).result({
|
|
919
|
+
before: /* @__PURE__ */ __name((val) => {
|
|
920
|
+
val.default_harm += Math.floor(val.default_harm * 0.2) + Math.floor(val.agent.self.mp * 0.1);
|
|
921
|
+
}, "before")
|
|
922
|
+
});
|
|
923
|
+
fn({
|
|
924
|
+
damage: damageData,
|
|
925
|
+
type: this.type,
|
|
926
|
+
target: [agent.goal],
|
|
927
|
+
isNext: false
|
|
928
|
+
});
|
|
929
|
+
return `${getLineupName(agent.self)} 释放水炮,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
930
|
+
}, "fn")
|
|
721
931
|
},
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
932
|
+
"濒死一击": {
|
|
933
|
+
name: "濒死一击",
|
|
934
|
+
type: "伤害技" /* 伤害技 */,
|
|
935
|
+
info: "[伤害技]血量低于40%可释放,消耗20MP,对敌方一个单位造成基于攻击力2倍伤害。该次伤害暴击率提高20%",
|
|
936
|
+
lv: 3,
|
|
937
|
+
mp: 20,
|
|
938
|
+
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
939
|
+
if (agent.self.hp / (agent.self.maxHp + agent.self.gain.maxHp) < 0.4) {
|
|
940
|
+
const damageData = new Damage(agent).result({
|
|
941
|
+
before: /* @__PURE__ */ __name((val) => {
|
|
942
|
+
val.default_harm += val.default_harm;
|
|
943
|
+
val.agent.self.chr += 200;
|
|
944
|
+
}, "before")
|
|
945
|
+
});
|
|
946
|
+
fn({
|
|
947
|
+
damage: damageData,
|
|
948
|
+
type: this.type,
|
|
949
|
+
target: [agent.goal],
|
|
950
|
+
isNext: false
|
|
951
|
+
});
|
|
952
|
+
return `${getLineupName(agent.self)} 释放濒死一击,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
953
|
+
} else {
|
|
954
|
+
fn({
|
|
955
|
+
type: "释放失败" /* 释放失败 */,
|
|
956
|
+
isNext: true,
|
|
957
|
+
err: "释放失败,未达成条件。"
|
|
958
|
+
});
|
|
959
|
+
return ``;
|
|
960
|
+
}
|
|
961
|
+
}, "fn")
|
|
749
962
|
},
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
963
|
+
"初级治愈": {
|
|
964
|
+
name: "初级治愈",
|
|
965
|
+
type: "治疗技" /* 治疗技 */,
|
|
966
|
+
info: "[治疗技]直接恢复自身或者目标 40HP",
|
|
967
|
+
lv: 1,
|
|
968
|
+
mp: 30,
|
|
969
|
+
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
970
|
+
const selectGoal = agent.goal;
|
|
971
|
+
if (agent.goal.hp <= 0) {
|
|
972
|
+
return `${getLineupName(agent.self)}已阵亡,无法恢复...`;
|
|
973
|
+
}
|
|
974
|
+
fn({
|
|
975
|
+
value: 40,
|
|
976
|
+
target: [selectGoal],
|
|
977
|
+
type: "治疗技" /* 治疗技 */,
|
|
978
|
+
isNext: false
|
|
979
|
+
});
|
|
980
|
+
return `${getLineupName(agent.self)}释放初级治愈,${getLineupName(agent.goal)}恢复40HP`;
|
|
981
|
+
}, "fn")
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
// src/battle.ts
|
|
986
|
+
var BattleData = {
|
|
987
|
+
config: {},
|
|
988
|
+
ctx: {},
|
|
989
|
+
historyTemp: {},
|
|
990
|
+
lastPlay: {},
|
|
991
|
+
teamTemp: {},
|
|
992
|
+
init(config, ctx) {
|
|
993
|
+
this.config = config;
|
|
994
|
+
this.ctx = ctx;
|
|
756
995
|
},
|
|
757
|
-
/**
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
if (!val) {
|
|
761
|
-
const { maxHp } = User.getUserAttributeByUserId(userId);
|
|
762
|
-
userInfo.hp = maxHp;
|
|
763
|
-
} else {
|
|
764
|
-
userInfo.hp = val;
|
|
765
|
-
}
|
|
766
|
-
await User.setDatabaseUserAttribute(userId);
|
|
996
|
+
/** 玩家是否正在战斗 */
|
|
997
|
+
isBattle(session) {
|
|
998
|
+
return !!BattleData.lastPlay[session.userId];
|
|
767
999
|
},
|
|
768
|
-
/**
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
userInfo.hp = maxHp;
|
|
785
|
-
}
|
|
786
|
-
if (userInfo.mp + (value.mp || 0) < maxHp) {
|
|
787
|
-
userInfo.mp += value.mp || 0;
|
|
788
|
-
} else {
|
|
789
|
-
userInfo.mp = maxMp;
|
|
1000
|
+
/** 玩家是否正在战斗 */
|
|
1001
|
+
isBattleByUserId(userId) {
|
|
1002
|
+
return !!BattleData.lastPlay[userId];
|
|
1003
|
+
},
|
|
1004
|
+
/** 玩家是否在队伍中 */
|
|
1005
|
+
isTeam(session) {
|
|
1006
|
+
return !!BattleData.teamTemp[session.userId];
|
|
1007
|
+
},
|
|
1008
|
+
isTeamByUserId(userId) {
|
|
1009
|
+
return !!BattleData.teamTemp[userId];
|
|
1010
|
+
},
|
|
1011
|
+
// 返回队伍信息
|
|
1012
|
+
teamListByUser(userId) {
|
|
1013
|
+
const teamList = [];
|
|
1014
|
+
if (!BattleData.teamTemp[userId]) {
|
|
1015
|
+
return [];
|
|
790
1016
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
1017
|
+
const _userId = BattleData.teamTemp[userId].for;
|
|
1018
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1019
|
+
if (BattleData.teamTemp[item].for == _userId) {
|
|
1020
|
+
teamList.push(User.getUserAttributeByUserId(item));
|
|
1021
|
+
}
|
|
794
1022
|
});
|
|
795
|
-
|
|
1023
|
+
return teamList;
|
|
796
1024
|
},
|
|
797
|
-
/**
|
|
798
|
-
async
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
1025
|
+
/** 创建战斗-与怪物 */
|
|
1026
|
+
async createBattleByMonster(session, goal) {
|
|
1027
|
+
if (BattleData.isBattle(session)) {
|
|
1028
|
+
await session.send("当前正在战斗,还不能逃脱!");
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
const battle_user = [];
|
|
1032
|
+
const battle_monsterList = [];
|
|
1033
|
+
const playUser = [];
|
|
1034
|
+
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1035
|
+
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1036
|
+
return;
|
|
1037
|
+
} else if (BattleData.isTeam(session)) {
|
|
1038
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1039
|
+
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1040
|
+
playUser.push(item);
|
|
1041
|
+
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
804
1044
|
} else {
|
|
805
|
-
|
|
1045
|
+
playUser.push(session.userId);
|
|
1046
|
+
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
806
1047
|
}
|
|
807
|
-
|
|
808
|
-
|
|
1048
|
+
goal.forEach((item) => {
|
|
1049
|
+
battle_monsterList.push(initBattleAttribute(Monster.getMonsterAttributeData(item.name, item.lv)));
|
|
809
1050
|
});
|
|
810
|
-
|
|
1051
|
+
const temp = {
|
|
1052
|
+
self: battle_user.map((i) => ({ ...i, for: "self" })),
|
|
1053
|
+
goal: battle_monsterList.map((i) => ({ ...i, for: "goal" }))
|
|
1054
|
+
};
|
|
1055
|
+
playUser.forEach((userId) => {
|
|
1056
|
+
BattleData.lastPlay[userId] = temp;
|
|
1057
|
+
});
|
|
1058
|
+
await session.send(`开始与 ${goal.map((i) => i.name).join("、")} 进行战斗`);
|
|
811
1059
|
},
|
|
812
|
-
/**
|
|
813
|
-
async
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
await User.ctx.monetary.gain(bindData.aid, val);
|
|
818
|
-
fn && fn({ val, currentVal: currentM.value += val });
|
|
1060
|
+
/** 创建战斗-与玩家 */
|
|
1061
|
+
async createBattleByUser(session, goal) {
|
|
1062
|
+
if (BattleData.isBattle(session)) {
|
|
1063
|
+
await session.send("当前正在战斗,还不能逃脱!");
|
|
1064
|
+
return;
|
|
819
1065
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
err: "余额不足!"
|
|
831
|
-
});
|
|
832
|
-
return;
|
|
1066
|
+
const battle_self = [];
|
|
1067
|
+
const battle_goal = [];
|
|
1068
|
+
const playUser = [];
|
|
1069
|
+
const lostMsg = [];
|
|
1070
|
+
goal = goal.filter((item) => {
|
|
1071
|
+
const isBattle = BattleData.isBattleByUserId(item.userId);
|
|
1072
|
+
const pyUser = User.userTempData[item.userId];
|
|
1073
|
+
if (isBattle) {
|
|
1074
|
+
lostMsg.push(`${pyUser.playName}正在参与着一场战斗,无法被PK选中。`);
|
|
1075
|
+
return false;
|
|
833
1076
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1077
|
+
return true;
|
|
1078
|
+
});
|
|
1079
|
+
if (lostMsg.length) {
|
|
1080
|
+
await session.send(lostMsg.join("\n"));
|
|
1081
|
+
}
|
|
1082
|
+
if (!goal.length) {
|
|
1083
|
+
lostMsg.push(`PK失败,无任何目标进行PK`);
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
|
|
1087
|
+
await session.send("你不是队伍的队长,无法主动操作战斗!");
|
|
1088
|
+
return;
|
|
1089
|
+
} else if (BattleData.isTeam(session)) {
|
|
1090
|
+
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1091
|
+
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1092
|
+
playUser.push(item);
|
|
1093
|
+
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1094
|
+
}
|
|
838
1095
|
});
|
|
1096
|
+
} else {
|
|
1097
|
+
playUser.push(session.userId);
|
|
1098
|
+
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
839
1099
|
}
|
|
1100
|
+
goal.forEach((item) => {
|
|
1101
|
+
playUser.push(item.userId);
|
|
1102
|
+
battle_goal.push(initBattleAttribute(User.getUserAttributeByUserId(item.userId)));
|
|
1103
|
+
});
|
|
1104
|
+
const pkTemp = {
|
|
1105
|
+
self: battle_self.map((i) => ({ ...i, for: "self" })),
|
|
1106
|
+
goal: battle_goal.map((i) => ({ ...i, for: "goal" })),
|
|
1107
|
+
isPK: true
|
|
1108
|
+
};
|
|
1109
|
+
playUser.forEach((userId) => {
|
|
1110
|
+
BattleData.lastPlay[userId] = pkTemp;
|
|
1111
|
+
});
|
|
1112
|
+
await session.send(`开始与玩家 ${battle_goal.map((i) => i.name).join("、")} 进行PK战斗`);
|
|
840
1113
|
},
|
|
841
|
-
/**
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
"小蜜蜂": {
|
|
853
|
-
name: "小蜜蜂",
|
|
854
|
-
type: "野怪" /* 野怪 */,
|
|
855
|
-
info: "幻想乡一层常见的生物",
|
|
856
|
-
pic: "http://smmcat.cn/run/gensokyo/小蜜蜂.png",
|
|
857
|
-
hp: 50,
|
|
858
|
-
maxHp: 50,
|
|
859
|
-
mp: 30,
|
|
860
|
-
maxMp: 30,
|
|
861
|
-
atk: 7,
|
|
862
|
-
def: 2,
|
|
863
|
-
chr: 50,
|
|
864
|
-
csr: 0,
|
|
865
|
-
evasion: 100,
|
|
866
|
-
hit: 1e3,
|
|
867
|
-
ghd: 1.2,
|
|
868
|
-
speed: 4,
|
|
869
|
-
giveExp: 10,
|
|
870
|
-
giveMonetary: 2
|
|
871
|
-
},
|
|
872
|
-
"小蜘蛛": {
|
|
873
|
-
name: "小蜘蛛",
|
|
874
|
-
type: "野怪" /* 野怪 */,
|
|
875
|
-
info: "幻想乡一层常见的生物",
|
|
876
|
-
pic: "http://smmcat.cn/run/gensokyo/小蜘蛛.png",
|
|
877
|
-
hp: 55,
|
|
878
|
-
maxHp: 55,
|
|
879
|
-
mp: 30,
|
|
880
|
-
maxMp: 30,
|
|
881
|
-
atk: 10,
|
|
882
|
-
def: 3,
|
|
883
|
-
chr: 50,
|
|
884
|
-
csr: 0,
|
|
885
|
-
evasion: 150,
|
|
886
|
-
hit: 1e3,
|
|
887
|
-
ghd: 1.2,
|
|
888
|
-
speed: 4,
|
|
889
|
-
giveExp: 12,
|
|
890
|
-
giveMonetary: 2
|
|
891
|
-
},
|
|
892
|
-
"dora": {
|
|
893
|
-
name: "dora",
|
|
894
|
-
type: "野怪" /* 野怪 */,
|
|
895
|
-
info: "偶尔出没在一层世界的奇怪生物",
|
|
896
|
-
pic: "http://smmcat.cn/run/gensokyo/dora.png",
|
|
897
|
-
hp: 88,
|
|
898
|
-
maxHp: 88,
|
|
899
|
-
mp: 10,
|
|
900
|
-
maxMp: 10,
|
|
901
|
-
atk: 20,
|
|
902
|
-
def: 5,
|
|
903
|
-
chr: 200,
|
|
904
|
-
csr: 0,
|
|
905
|
-
evasion: 200,
|
|
906
|
-
hit: 1e3,
|
|
907
|
-
ghd: 1.2,
|
|
908
|
-
speed: 4,
|
|
909
|
-
giveExp: 15,
|
|
910
|
-
giveMonetary: 3
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
|
|
914
|
-
// src/monster.ts
|
|
915
|
-
var Monster = {
|
|
916
|
-
config: {},
|
|
917
|
-
ctx: {},
|
|
918
|
-
monsterTempData: {},
|
|
919
|
-
async init(config, ctx) {
|
|
920
|
-
Monster.config = config;
|
|
921
|
-
Monster.ctx = ctx;
|
|
922
|
-
ctx.model.extend(
|
|
923
|
-
"smm_gensokyo_monster_attribute",
|
|
924
|
-
{
|
|
925
|
-
id: "integer",
|
|
926
|
-
name: "string",
|
|
927
|
-
info: "string",
|
|
928
|
-
type: "string",
|
|
929
|
-
hp: "integer",
|
|
930
|
-
maxHp: "integer",
|
|
931
|
-
mp: "integer",
|
|
932
|
-
maxMp: "integer",
|
|
933
|
-
atk: "integer",
|
|
934
|
-
def: "integer",
|
|
935
|
-
chr: "integer",
|
|
936
|
-
evasion: "integer",
|
|
937
|
-
hit: "integer",
|
|
938
|
-
ghd: "integer",
|
|
939
|
-
speed: "integer"
|
|
940
|
-
},
|
|
941
|
-
{
|
|
942
|
-
primary: "id",
|
|
943
|
-
autoInc: false
|
|
1114
|
+
/** 文本化当前战况 */
|
|
1115
|
+
battleSituationTextFormat(team) {
|
|
1116
|
+
const selfTemp = [];
|
|
1117
|
+
const goalTemp = [];
|
|
1118
|
+
team.self.forEach((item) => {
|
|
1119
|
+
if (item.hp > 0) {
|
|
1120
|
+
selfTemp.push(`lv.${item.lv}[${item.name}]:
|
|
1121
|
+
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1122
|
+
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1123
|
+
} else {
|
|
1124
|
+
selfTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
944
1125
|
}
|
|
945
|
-
);
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
954
|
-
|
|
1126
|
+
});
|
|
1127
|
+
team.goal.forEach((item) => {
|
|
1128
|
+
if (item.hp > 0) {
|
|
1129
|
+
goalTemp.push(`lv.${item.lv}[${item.name}]:
|
|
1130
|
+
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1131
|
+
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1132
|
+
} else {
|
|
1133
|
+
goalTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
if (team.isPK) {
|
|
1137
|
+
return `[当前战况]
|
|
1138
|
+
攻击方:
|
|
1139
|
+
` + selfTemp.join("\n") + "\n\n防御方:\n" + goalTemp.join("\n");
|
|
955
1140
|
}
|
|
1141
|
+
return `[当前战况]
|
|
1142
|
+
我方阵容:
|
|
1143
|
+
` + selfTemp.join("\n") + "\n\n敌方阵容:\n" + goalTemp.join("\n");
|
|
956
1144
|
},
|
|
957
|
-
/**
|
|
958
|
-
|
|
959
|
-
|
|
1145
|
+
/** 判断输赢 */
|
|
1146
|
+
playOver(team) {
|
|
1147
|
+
const self = team.self.every((item) => item.hp <= 0);
|
|
1148
|
+
const goal = team.goal.every((item) => item.hp <= 0);
|
|
1149
|
+
if (self && goal) {
|
|
1150
|
+
return { over: true, type: "平局", win: "" };
|
|
1151
|
+
} else if (self) {
|
|
1152
|
+
return { over: true, type: team.isPK ? "防御方赢" : "敌方赢", win: "goal" };
|
|
1153
|
+
} else if (goal) {
|
|
1154
|
+
return { over: true, type: team.isPK ? "攻击方赢" : "我方赢", win: "self" };
|
|
1155
|
+
}
|
|
1156
|
+
return { over: false, type: "未结束", win: "" };
|
|
960
1157
|
},
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
Object.keys(monster).forEach((i) => {
|
|
969
|
-
temp[i] = monster[i];
|
|
970
|
-
if (useBenchmark[i]) {
|
|
971
|
-
temp[i] += Math.floor(temp[i] * (useBenchmark[i] - 1) * (lv - 1));
|
|
1158
|
+
/** 清理战场 */
|
|
1159
|
+
clearBattleData(session) {
|
|
1160
|
+
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1161
|
+
const allAgentList = [...currentBattle.goal, ...currentBattle.self];
|
|
1162
|
+
allAgentList.forEach((item) => {
|
|
1163
|
+
if (item.type == "玩家") {
|
|
1164
|
+
delete BattleData.lastPlay[item.userId];
|
|
972
1165
|
}
|
|
973
1166
|
});
|
|
974
|
-
return temp;
|
|
975
1167
|
},
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
【怪物类型】${type}
|
|
982
|
-
【生命值】${hp}/${maxHp}
|
|
983
|
-
【魔法值】${mp}/${maxMp}
|
|
984
|
-
【攻击力】${atk}
|
|
985
|
-
【防御力】${def}
|
|
986
|
-
【闪避值】${evasion}
|
|
987
|
-
【命中值】${hit}
|
|
988
|
-
【速度值】${speed}
|
|
989
|
-
【暴击率】${(chr / 10).toFixed(1)}%
|
|
990
|
-
【爆伤倍率】${(ghd * 100).toFixed(0)}%` + (info ? "\n\n" + info : "");
|
|
991
|
-
return attributeText;
|
|
992
|
-
}
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
// src/utlis.ts
|
|
996
|
-
var random = /* @__PURE__ */ __name((min, max) => {
|
|
997
|
-
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
998
|
-
}, "random");
|
|
999
|
-
var generateHealthDisplay = /* @__PURE__ */ __name((current, total) => {
|
|
1000
|
-
const ratio = current / total;
|
|
1001
|
-
const displayLength = 10;
|
|
1002
|
-
const filledLength = Math.floor(ratio * displayLength);
|
|
1003
|
-
const unfilledLength = displayLength - filledLength;
|
|
1004
|
-
const filled = "■".repeat(filledLength);
|
|
1005
|
-
const unfilled = "□".repeat(unfilledLength);
|
|
1006
|
-
return filled + unfilled;
|
|
1007
|
-
}, "generateHealthDisplay");
|
|
1008
|
-
|
|
1009
|
-
// src/damage.ts
|
|
1010
|
-
var Damage = class {
|
|
1011
|
-
static {
|
|
1012
|
-
__name(this, "Damage");
|
|
1013
|
-
}
|
|
1014
|
-
config;
|
|
1015
|
-
constructor(agent, realHarm = false) {
|
|
1016
|
-
this.config = {
|
|
1017
|
-
agent: { self: { ...agent.self }, goal: { ...agent.goal } },
|
|
1018
|
-
harm: 0,
|
|
1019
|
-
default_harm: 0,
|
|
1020
|
-
isRealHarm: realHarm,
|
|
1021
|
-
isEvasion: false,
|
|
1022
|
-
isCsp: false,
|
|
1023
|
-
isBadDef: false
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
/** 伤害判定前 */
|
|
1027
|
-
before(fn) {
|
|
1028
|
-
this.config.default_harm = this.config.agent.self.atk + this.config.agent.self.gain.atk;
|
|
1029
|
-
fn && fn(this.config);
|
|
1030
|
-
return this;
|
|
1031
|
-
}
|
|
1032
|
-
/** 真实伤害判定 */
|
|
1033
|
-
beforRealHarm(fn) {
|
|
1034
|
-
fn && fn(this.config);
|
|
1035
|
-
if (this.config.isRealHarm) {
|
|
1036
|
-
this.config.harm = this.config.default_harm;
|
|
1168
|
+
async play(session, atkType, select) {
|
|
1169
|
+
if (!BattleData.isBattle(session)) {
|
|
1170
|
+
await session.send("您并没有任何参与战斗。");
|
|
1171
|
+
return;
|
|
1037
1172
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1173
|
+
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1174
|
+
const allAgentList = [...currentBattle.goal, ...currentBattle.self].sort((a, b) => b.speed - a.speed);
|
|
1175
|
+
const msgList = [];
|
|
1176
|
+
for (const agent of allAgentList) {
|
|
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
|
+
}
|
|
1184
|
+
let lifeGoalList = [];
|
|
1185
|
+
let lifeSelfList = [];
|
|
1186
|
+
if (agent.for == "self") {
|
|
1187
|
+
lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1188
|
+
lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1189
|
+
} else {
|
|
1190
|
+
lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1191
|
+
lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1192
|
+
}
|
|
1193
|
+
if (!lifeGoalList.length) continue;
|
|
1194
|
+
let selectGoal = {};
|
|
1195
|
+
let isMy = false;
|
|
1196
|
+
let funType = "普攻";
|
|
1197
|
+
if (agent.type == "玩家" && agent.userId == session.userId) {
|
|
1198
|
+
isMy = true;
|
|
1199
|
+
funType = atkType;
|
|
1200
|
+
selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1201
|
+
} else if (agent.type == "玩家") {
|
|
1202
|
+
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1203
|
+
} else {
|
|
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
|
+
}
|
|
1050
1258
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
const cspVal = (self.chr + self.gain.chr - goal.csr) / 10;
|
|
1060
|
-
if (random(0, 100) <= cspVal) {
|
|
1061
|
-
this.config.isCsp = true;
|
|
1062
|
-
this.config.harm = Math.floor(this.config.default_harm * (self.ghd + self.gain.ghd));
|
|
1063
|
-
fn && fn(this.config);
|
|
1064
|
-
return this;
|
|
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);
|
|
1065
1267
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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
|
+
}
|
|
1079
1314
|
} else {
|
|
1080
|
-
|
|
1081
|
-
|
|
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
|
+
}
|
|
1082
1353
|
}
|
|
1083
|
-
return this;
|
|
1084
|
-
}
|
|
1085
|
-
result(fn) {
|
|
1086
|
-
this.before((val) => {
|
|
1087
|
-
fn?.before && fn.before(val);
|
|
1088
|
-
}).beforRealHarm((val) => {
|
|
1089
|
-
fn?.beforRealHarm && fn.beforRealHarm(val);
|
|
1090
|
-
}).evasion((val) => {
|
|
1091
|
-
fn?.evasion && fn.evasion(val);
|
|
1092
|
-
}).csp((val) => {
|
|
1093
|
-
fn?.csp && fn.csp(val);
|
|
1094
|
-
}).beforDef((val) => {
|
|
1095
|
-
fn?.beforDef && fn.beforDef(val);
|
|
1096
|
-
});
|
|
1097
|
-
return this.config;
|
|
1098
1354
|
}
|
|
1099
1355
|
};
|
|
1100
|
-
function
|
|
1101
|
-
|
|
1102
|
-
goal.hp -= damage.harm;
|
|
1103
|
-
return damage.harm;
|
|
1104
|
-
} else {
|
|
1105
|
-
const lostHp = goal.hp;
|
|
1106
|
-
goal.hp = 0;
|
|
1107
|
-
return lostHp;
|
|
1108
|
-
}
|
|
1356
|
+
function getLineupName(agent) {
|
|
1357
|
+
return `[${agent.type}]${agent.name}`;
|
|
1109
1358
|
}
|
|
1110
|
-
__name(
|
|
1111
|
-
function
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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;
|
|
1116
1395
|
} else {
|
|
1117
|
-
const
|
|
1118
|
-
|
|
1119
|
-
|
|
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;
|
|
1120
1428
|
}
|
|
1121
1429
|
}
|
|
1122
|
-
__name(
|
|
1123
|
-
function moreDamageInfo(damage) {
|
|
1124
|
-
return (damage.isCsp ? `(暴击!)` : "") + (damage.isEvasion ? `(闪避成功!)` : "") + (damage.isBadDef ? `(未破防!)` : "");
|
|
1125
|
-
}
|
|
1126
|
-
__name(moreDamageInfo, "moreDamageInfo");
|
|
1430
|
+
__name(initBattleAttribute, "initBattleAttribute");
|
|
1127
1431
|
|
|
1128
|
-
// src/
|
|
1129
|
-
var
|
|
1130
|
-
"
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
name: "突刺",
|
|
1155
|
-
type: "伤害技" /* 伤害技 */,
|
|
1156
|
-
info: "[伤害技]消耗10MP,对敌方一个单位造成基于攻击力1.2倍伤害,该伤害无视敌方闪避10%",
|
|
1157
|
-
lv: 3,
|
|
1158
|
-
mp: 10,
|
|
1159
|
-
feature: ["刺客" /* 刺客 */],
|
|
1160
|
-
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
1161
|
-
const damageData = new Damage(agent).result({
|
|
1162
|
-
before: /* @__PURE__ */ __name((val) => {
|
|
1163
|
-
val.default_harm += Math.floor(val.default_harm * 0.2);
|
|
1164
|
-
val.agent.goal.evasion -= Math.floor((val.agent.goal.evasion + val.agent.goal.gain.evasion) * 0.1);
|
|
1165
|
-
}, "before")
|
|
1166
|
-
});
|
|
1167
|
-
fn({
|
|
1168
|
-
damage: damageData,
|
|
1169
|
-
type: this.type,
|
|
1170
|
-
target: [agent.goal],
|
|
1171
|
-
isNext: false
|
|
1172
|
-
});
|
|
1173
|
-
return `${getLineupName(agent.self)} 释放突刺,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
1174
|
-
}, "fn")
|
|
1175
|
-
},
|
|
1176
|
-
"水炮": {
|
|
1177
|
-
name: "水炮",
|
|
1178
|
-
type: "伤害技" /* 伤害技 */,
|
|
1179
|
-
info: "[伤害技]消耗10MP,通过凝集魔力对敌方造成基于攻击力1.2倍伤害,该伤害基于当前剩余魔法值10%额外叠加伤害。",
|
|
1180
|
-
lv: 3,
|
|
1181
|
-
mp: 10,
|
|
1182
|
-
feature: ["法师" /* 法师 */],
|
|
1183
|
-
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
1184
|
-
const damageData = new Damage(agent).result({
|
|
1185
|
-
before: /* @__PURE__ */ __name((val) => {
|
|
1186
|
-
val.default_harm += Math.floor(val.default_harm * 0.2) + Math.floor(val.agent.self.mp * 0.1);
|
|
1187
|
-
}, "before")
|
|
1188
|
-
});
|
|
1189
|
-
fn({
|
|
1190
|
-
damage: damageData,
|
|
1191
|
-
type: this.type,
|
|
1192
|
-
target: [agent.goal],
|
|
1193
|
-
isNext: false
|
|
1194
|
-
});
|
|
1195
|
-
return `${getLineupName(agent.self)} 释放水炮,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
1196
|
-
}, "fn")
|
|
1197
|
-
},
|
|
1198
|
-
"濒死一击": {
|
|
1199
|
-
name: "濒死一击",
|
|
1200
|
-
type: "伤害技" /* 伤害技 */,
|
|
1201
|
-
info: "[伤害技]血量低于40%可释放,消耗20MP,对敌方一个单位造成基于攻击力2倍伤害。该次伤害暴击率提高20%",
|
|
1202
|
-
lv: 3,
|
|
1203
|
-
mp: 20,
|
|
1204
|
-
fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
|
|
1205
|
-
if (agent.self.hp / (agent.self.maxHp + agent.self.gain.maxHp) < 0.4) {
|
|
1206
|
-
const damageData = new Damage(agent).result({
|
|
1207
|
-
before: /* @__PURE__ */ __name((val) => {
|
|
1208
|
-
val.default_harm += val.default_harm;
|
|
1209
|
-
val.agent.self.chr += 200;
|
|
1210
|
-
}, "before")
|
|
1211
|
-
});
|
|
1212
|
-
fn({
|
|
1213
|
-
damage: damageData,
|
|
1214
|
-
type: this.type,
|
|
1215
|
-
target: [agent.goal],
|
|
1216
|
-
isNext: false
|
|
1217
|
-
});
|
|
1218
|
-
return `${getLineupName(agent.self)} 释放濒死一击,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
|
|
1219
|
-
} else {
|
|
1220
|
-
fn({
|
|
1221
|
-
type: "释放失败" /* 释放失败 */,
|
|
1222
|
-
isNext: true,
|
|
1223
|
-
err: "释放失败,未达成条件。"
|
|
1224
|
-
});
|
|
1225
|
-
return ``;
|
|
1226
|
-
}
|
|
1227
|
-
}, "fn")
|
|
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
|
+
}
|
|
1228
1458
|
},
|
|
1229
|
-
"
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
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
|
+
}
|
|
1245
1508
|
}
|
|
1246
1509
|
};
|
|
1247
|
-
|
|
1248
|
-
// src/battle.ts
|
|
1249
|
-
var BattleData = {
|
|
1510
|
+
var User = {
|
|
1250
1511
|
config: {},
|
|
1251
1512
|
ctx: {},
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
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;
|
|
1273
1541
|
},
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
return
|
|
1542
|
+
/** 获取角色基础属性 */
|
|
1543
|
+
async getUserAttribute(session) {
|
|
1544
|
+
if (!User.userTempData[session.userId]) {
|
|
1545
|
+
await session.send("未创建账户,请发送 /开始注册 完成账号的注册!");
|
|
1546
|
+
return null;
|
|
1279
1547
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
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
|
+
}
|
|
1284
1576
|
}
|
|
1285
1577
|
});
|
|
1286
|
-
return
|
|
1578
|
+
return temp;
|
|
1287
1579
|
},
|
|
1288
|
-
/**
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
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("已存在账号,请勿重复创建!");
|
|
1292
1589
|
return;
|
|
1293
1590
|
}
|
|
1294
|
-
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
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("名字重复,请更换一个名字。");
|
|
1299
1597
|
return;
|
|
1300
|
-
} else if (BattleData.isTeam(session)) {
|
|
1301
|
-
Object.keys(BattleData.teamTemp).forEach((item) => {
|
|
1302
|
-
if (BattleData.teamTemp[item].for == session.userId) {
|
|
1303
|
-
playUser.push(item);
|
|
1304
|
-
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
|
|
1305
|
-
}
|
|
1306
|
-
});
|
|
1307
|
-
} else {
|
|
1308
|
-
playUser.push(session.userId);
|
|
1309
|
-
battle_user.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
1310
1598
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
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;
|
|
1314
1654
|
const temp = {
|
|
1315
|
-
|
|
1316
|
-
|
|
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
|
|
1317
1661
|
};
|
|
1318
|
-
|
|
1319
|
-
BattleData.lastPlay[userId] = temp;
|
|
1320
|
-
});
|
|
1321
|
-
await session.send(`开始与 ${goal.map((i) => i.name).join("、")} 进行战斗`);
|
|
1662
|
+
User.ctx.database.set("smm_gensokyo_user_attribute", { userId }, temp);
|
|
1322
1663
|
},
|
|
1323
|
-
/**
|
|
1324
|
-
async
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
if (isBattle) {
|
|
1337
|
-
lostMsg.push(`${pyUser.playName}正在参与着一场战斗,无法被PK选中。`);
|
|
1338
|
-
return false;
|
|
1339
|
-
}
|
|
1340
|
-
return true;
|
|
1341
|
-
});
|
|
1342
|
-
if (lostMsg.length) {
|
|
1343
|
-
await session.send(lostMsg.join("\n"));
|
|
1344
|
-
}
|
|
1345
|
-
if (!goal.length) {
|
|
1346
|
-
lostMsg.push(`PK失败,无任何目标进行PK`);
|
|
1347
|
-
return;
|
|
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;
|
|
1348
1677
|
}
|
|
1349
|
-
if (
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
playUser.push(session.userId);
|
|
1361
|
-
battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
|
|
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);
|
|
1362
1689
|
}
|
|
1363
|
-
|
|
1364
|
-
playUser.push(item.userId);
|
|
1365
|
-
battle_goal.push(initBattleAttribute(User.getUserAttributeByUserId(item.userId)));
|
|
1366
|
-
});
|
|
1367
|
-
const pkTemp = {
|
|
1368
|
-
self: battle_self.map((i) => ({ ...i, for: "self" })),
|
|
1369
|
-
goal: battle_goal.map((i) => ({ ...i, for: "goal" })),
|
|
1370
|
-
isPK: true
|
|
1371
|
-
};
|
|
1372
|
-
playUser.forEach((userId) => {
|
|
1373
|
-
BattleData.lastPlay[userId] = pkTemp;
|
|
1374
|
-
});
|
|
1375
|
-
await session.send(`开始与玩家 ${battle_goal.map((i) => i.name).join("、")} 进行PK战斗`);
|
|
1690
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1376
1691
|
},
|
|
1377
|
-
/**
|
|
1378
|
-
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
selfTemp.push(`lv.${item.lv}[${item.name}]:
|
|
1384
|
-
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1385
|
-
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1386
|
-
} else {
|
|
1387
|
-
selfTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1388
|
-
}
|
|
1389
|
-
});
|
|
1390
|
-
team.goal.forEach((item) => {
|
|
1391
|
-
if (item.hp > 0) {
|
|
1392
|
-
goalTemp.push(`lv.${item.lv}[${item.name}]:
|
|
1393
|
-
${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
|
|
1394
|
-
MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
|
|
1395
|
-
} else {
|
|
1396
|
-
goalTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
if (team.isPK) {
|
|
1400
|
-
return `[当前战况]
|
|
1401
|
-
攻击方:
|
|
1402
|
-
` + selfTemp.join("\n") + "\n\n防御方:\n" + goalTemp.join("\n");
|
|
1403
|
-
}
|
|
1404
|
-
return `[当前战况]
|
|
1405
|
-
我方阵容:
|
|
1406
|
-
` + selfTemp.join("\n") + "\n\n敌方阵容:\n" + goalTemp.join("\n");
|
|
1692
|
+
/** 给予玩家死亡 */
|
|
1693
|
+
async giveDie(userId) {
|
|
1694
|
+
const userInfo = User.userTempData[userId];
|
|
1695
|
+
userInfo.hp = 0;
|
|
1696
|
+
userInfo.isDie = true;
|
|
1697
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1407
1698
|
},
|
|
1408
|
-
/**
|
|
1409
|
-
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
} else
|
|
1415
|
-
|
|
1416
|
-
} else if (goal) {
|
|
1417
|
-
return { over: true, type: team.isPK ? "攻击方赢" : "我方赢", win: "self" };
|
|
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;
|
|
1418
1707
|
}
|
|
1419
|
-
|
|
1420
|
-
},
|
|
1421
|
-
/** 清理战场 */
|
|
1422
|
-
clearBattleData(session) {
|
|
1423
|
-
const currentBattle = BattleData.lastPlay[session.userId];
|
|
1424
|
-
const allAgentList = [...currentBattle.goal, ...currentBattle.self];
|
|
1425
|
-
allAgentList.forEach((item) => {
|
|
1426
|
-
if (item.type == "玩家") {
|
|
1427
|
-
delete BattleData.lastPlay[item.userId];
|
|
1428
|
-
}
|
|
1429
|
-
});
|
|
1708
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1430
1709
|
},
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
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
|
+
});
|
|
1434
1720
|
return;
|
|
1435
1721
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
if (agent
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
if (agent.for == "self") {
|
|
1444
|
-
lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1445
|
-
lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1446
|
-
} else {
|
|
1447
|
-
lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
|
|
1448
|
-
lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
|
|
1449
|
-
}
|
|
1450
|
-
if (!lifeGoalList.length) continue;
|
|
1451
|
-
let selectGoal = {};
|
|
1452
|
-
let isMy = false;
|
|
1453
|
-
let funType = "普攻";
|
|
1454
|
-
if (agent.type == "玩家" && agent.userId == session.userId) {
|
|
1455
|
-
isMy = true;
|
|
1456
|
-
funType = atkType;
|
|
1457
|
-
selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
1458
|
-
} else if (agent.type == "玩家") {
|
|
1459
|
-
selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
|
|
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;
|
|
1460
1729
|
} else {
|
|
1461
|
-
|
|
1730
|
+
agent.hp = agent.maxHp;
|
|
1462
1731
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
giveDamage(agent, selectGoal, damageInfo);
|
|
1466
|
-
msgList.push(
|
|
1467
|
-
`${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
|
|
1468
|
-
);
|
|
1469
|
-
}, "noralAtk");
|
|
1470
|
-
if (funType == "普攻") {
|
|
1471
|
-
noralAtk();
|
|
1732
|
+
if (agent.mp + (value.mp || 0) < agent.maxMp) {
|
|
1733
|
+
agent.mp += value.mp || 0;
|
|
1472
1734
|
} else {
|
|
1473
|
-
|
|
1474
|
-
if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[atkType].type)) {
|
|
1475
|
-
selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
|
|
1476
|
-
}
|
|
1477
|
-
const selectFn = skillFn[atkType];
|
|
1478
|
-
if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
|
|
1479
|
-
agent.mp -= selectFn.mp;
|
|
1480
|
-
let isNext = false;
|
|
1481
|
-
const fnMsg = selectFn.fn(
|
|
1482
|
-
{ self: agent, goal: selectGoal },
|
|
1483
|
-
{ selfList: lifeSelfList, goalList: lifeGoalList },
|
|
1484
|
-
(val) => {
|
|
1485
|
-
switch (val.type) {
|
|
1486
|
-
case "伤害技" /* 伤害技 */:
|
|
1487
|
-
val.target.map((goal) => {
|
|
1488
|
-
giveDamage(agent, goal, val.damage);
|
|
1489
|
-
});
|
|
1490
|
-
break;
|
|
1491
|
-
case "治疗技" /* 治疗技 */:
|
|
1492
|
-
val.target.map((goal) => {
|
|
1493
|
-
giveCure(goal, val.value);
|
|
1494
|
-
});
|
|
1495
|
-
break;
|
|
1496
|
-
case "释放失败" /* 释放失败 */:
|
|
1497
|
-
val.err && session.send(val.err);
|
|
1498
|
-
default:
|
|
1499
|
-
break;
|
|
1500
|
-
}
|
|
1501
|
-
isNext = val.isNext;
|
|
1502
|
-
}
|
|
1503
|
-
);
|
|
1504
|
-
fnMsg && msgList.push(fnMsg);
|
|
1505
|
-
isNext && noralAtk();
|
|
1506
|
-
} else {
|
|
1507
|
-
await session.send(`MP不足,释放失败!`);
|
|
1508
|
-
noralAtk();
|
|
1509
|
-
}
|
|
1510
|
-
} else {
|
|
1511
|
-
await session.send(`未持有该技能或者该技能不存在,释放失败!`);
|
|
1512
|
-
noralAtk();
|
|
1513
|
-
}
|
|
1735
|
+
agent.mp = agent.maxMp;
|
|
1514
1736
|
}
|
|
1737
|
+
fn && await fn({
|
|
1738
|
+
currentHP: agent.hp,
|
|
1739
|
+
currentMP: agent.mp
|
|
1740
|
+
});
|
|
1741
|
+
return;
|
|
1515
1742
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
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;
|
|
1524
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;
|
|
1777
|
+
}
|
|
1778
|
+
fn && await fn({
|
|
1779
|
+
currentHP: userInfo.hp,
|
|
1780
|
+
currentMP: userInfo.mp
|
|
1781
|
+
});
|
|
1782
|
+
await User.setDatabaseUserAttribute(userId);
|
|
1525
1783
|
},
|
|
1526
|
-
/**
|
|
1527
|
-
async
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
const
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
` + (val.atk ? `攻击力↑ ${val.atk}
|
|
1534
|
-
` : "") + (val.def ? `防御力↑ ${val.def}
|
|
1535
|
-
` : "") + (val.maxHp ? `最大血量↑ ${val.maxHp}
|
|
1536
|
-
` : "") + (val.maxMp ? `最大蓝量↑ ${val.maxMp}` : "");
|
|
1537
|
-
await session.send(msgTemp);
|
|
1538
|
-
}, "msg");
|
|
1539
|
-
const aynchronize = /* @__PURE__ */ __name((agent) => {
|
|
1540
|
-
User.userTempData[agent.userId].hp = agent.hp;
|
|
1541
|
-
User.userTempData[agent.userId].mp = agent.mp;
|
|
1542
|
-
}, "aynchronize");
|
|
1543
|
-
if (tempData.isPK) {
|
|
1544
|
-
if (overInfo.win == "self") {
|
|
1545
|
-
await session.send("攻击方获得20EXP、5货币");
|
|
1546
|
-
for (const agent of allList) {
|
|
1547
|
-
aynchronize(agent);
|
|
1548
|
-
if (agent.for == "self") {
|
|
1549
|
-
if (agent.hp <= 0) {
|
|
1550
|
-
User.userTempData[agent.userId].hp = 0;
|
|
1551
|
-
User.userTempData[agent.userId].isDie = true;
|
|
1552
|
-
}
|
|
1553
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1554
|
-
await User.giveMonetary(agent.userId, 5);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
} else if (overInfo.win == "goal") {
|
|
1558
|
-
await session.send("防御方获得20EXP、5货币");
|
|
1559
|
-
for (const agent of allList) {
|
|
1560
|
-
aynchronize(agent);
|
|
1561
|
-
if (agent.for == "goal") {
|
|
1562
|
-
if (agent.hp <= 0) {
|
|
1563
|
-
User.userTempData[agent.userId].hp = 0;
|
|
1564
|
-
User.userTempData[agent.userId].isDie = true;
|
|
1565
|
-
}
|
|
1566
|
-
await User.giveExp(agent.userId, 20, async (val) => await msg(val));
|
|
1567
|
-
await User.giveMonetary(agent.userId, 5);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
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;
|
|
1571
1791
|
} else {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
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值不够,消耗失败!"
|
|
1581
1806
|
});
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
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;
|
|
1589
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;
|
|
1590
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;
|
|
1591
1901
|
}
|
|
1592
1902
|
};
|
|
1593
|
-
function getLineupName(agent) {
|
|
1594
|
-
return `[${agent.type}]${agent.name}`;
|
|
1595
|
-
}
|
|
1596
|
-
__name(getLineupName, "getLineupName");
|
|
1597
|
-
function initBattleAttribute(data) {
|
|
1598
|
-
if ("playName" in data) {
|
|
1599
|
-
const userData = data;
|
|
1600
|
-
const temp = {
|
|
1601
|
-
userId: userData.userId,
|
|
1602
|
-
name: userData.playName,
|
|
1603
|
-
lv: userData.lv,
|
|
1604
|
-
type: "玩家",
|
|
1605
|
-
hp: userData.hp,
|
|
1606
|
-
maxHp: userData.maxHp,
|
|
1607
|
-
mp: userData.mp,
|
|
1608
|
-
maxMp: userData.maxMp,
|
|
1609
|
-
atk: userData.atk,
|
|
1610
|
-
def: userData.def,
|
|
1611
|
-
chr: userData.chr,
|
|
1612
|
-
ghd: userData.ghd,
|
|
1613
|
-
csr: userData.csr,
|
|
1614
|
-
evasion: userData.evasion,
|
|
1615
|
-
hit: userData.hit,
|
|
1616
|
-
speed: userData.speed,
|
|
1617
|
-
gain: {
|
|
1618
|
-
maxHp: 0,
|
|
1619
|
-
maxMp: 0,
|
|
1620
|
-
atk: 0,
|
|
1621
|
-
def: 0,
|
|
1622
|
-
chr: 0,
|
|
1623
|
-
ghd: 0,
|
|
1624
|
-
evasion: 0,
|
|
1625
|
-
hit: 0,
|
|
1626
|
-
speed: 0
|
|
1627
|
-
},
|
|
1628
|
-
buff: [],
|
|
1629
|
-
fn: []
|
|
1630
|
-
};
|
|
1631
|
-
return temp;
|
|
1632
|
-
} else {
|
|
1633
|
-
const monsterData2 = data;
|
|
1634
|
-
const temp = {
|
|
1635
|
-
name: monsterData2.name,
|
|
1636
|
-
type: "怪物",
|
|
1637
|
-
lv: monsterData2.lv,
|
|
1638
|
-
hp: monsterData2.hp,
|
|
1639
|
-
maxHp: monsterData2.maxHp,
|
|
1640
|
-
mp: monsterData2.mp,
|
|
1641
|
-
maxMp: monsterData2.maxMp,
|
|
1642
|
-
atk: monsterData2.atk,
|
|
1643
|
-
def: monsterData2.def,
|
|
1644
|
-
chr: monsterData2.chr,
|
|
1645
|
-
ghd: monsterData2.ghd,
|
|
1646
|
-
csr: monsterData2.csr,
|
|
1647
|
-
evasion: monsterData2.evasion,
|
|
1648
|
-
hit: monsterData2.hit,
|
|
1649
|
-
speed: monsterData2.speed,
|
|
1650
|
-
gain: {
|
|
1651
|
-
maxHp: 0,
|
|
1652
|
-
maxMp: 0,
|
|
1653
|
-
atk: 0,
|
|
1654
|
-
def: 0,
|
|
1655
|
-
chr: 0,
|
|
1656
|
-
ghd: 0,
|
|
1657
|
-
evasion: 0,
|
|
1658
|
-
hit: 0,
|
|
1659
|
-
speed: 0
|
|
1660
|
-
},
|
|
1661
|
-
buff: [],
|
|
1662
|
-
fn: []
|
|
1663
|
-
};
|
|
1664
|
-
return temp;
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
__name(initBattleAttribute, "initBattleAttribute");
|
|
1668
1903
|
|
|
1669
1904
|
// src/index.ts
|
|
1670
1905
|
var name = "smmcat-gensokyo";
|
|
@@ -1786,10 +2021,22 @@ function apply(ctx, config) {
|
|
|
1786
2021
|
await session.send(GensokyoMap.userAreaTextFormat(userData.playName, query));
|
|
1787
2022
|
});
|
|
1788
2023
|
ctx.command("幻想乡/个人属性").action(async ({ session }) => {
|
|
2024
|
+
const userData = await User.getUserAttribute(session);
|
|
2025
|
+
if (!userData) return;
|
|
2026
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
1789
2027
|
return `您的属性如下:
|
|
1790
2028
|
` + User.userAttributeTextFormat(session.userId);
|
|
1791
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
|
+
});
|
|
1792
2036
|
ctx.command("幻想乡/个人信息").userFields(["id"]).action(async ({ session }) => {
|
|
2037
|
+
const userData = await User.getUserAttribute(session);
|
|
2038
|
+
if (!userData) return;
|
|
2039
|
+
GensokyoMap.initUserPoistion(session, userData);
|
|
1793
2040
|
const [data] = await ctx.database.get("monetary", { uid: session.user.id });
|
|
1794
2041
|
return `[${User.userTempData[session.userId].playName}]:您当前货币为:${data?.value || 0}个`;
|
|
1795
2042
|
});
|
|
@@ -1861,6 +2108,15 @@ function apply(ctx, config) {
|
|
|
1861
2108
|
await BattleData.createBattleByUser(session, [{ userId: exist.userId }]);
|
|
1862
2109
|
}
|
|
1863
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
|
+
});
|
|
1864
2120
|
ctx.command("幻想乡/技能查询 <goal>").action(async ({ session }, goal) => {
|
|
1865
2121
|
if (!goal) return `请输入技能名,例如 /技能查询 重砍`;
|
|
1866
2122
|
if (!skillFn[goal]) return `没有存在 ${goal} 技能!`;
|