koishi-plugin-ggcevo-game 1.2.71 → 1.2.73
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.d.ts +6 -1
- package/lib/index.js +847 -358
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -32,8 +32,7 @@ var name = "ggcevo-game";
|
|
|
32
32
|
var Config = import_koishi.Schema.intersect([
|
|
33
33
|
// 基础配置组
|
|
34
34
|
import_koishi.Schema.object({
|
|
35
|
-
proxyAgent: import_koishi.Schema.string().description("代理服务器地址")
|
|
36
|
-
ggcqun: import_koishi.Schema.string().description("绑定咕咕虫evo的群组ID").required()
|
|
35
|
+
proxyAgent: import_koishi.Schema.string().description("代理服务器地址")
|
|
37
36
|
}).description("基础设置"),
|
|
38
37
|
// 赛季与兑换配置组
|
|
39
38
|
import_koishi.Schema.object({
|
|
@@ -54,7 +53,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
54
53
|
}).description("对战限制"),
|
|
55
54
|
// 通知系统配置组
|
|
56
55
|
import_koishi.Schema.object({
|
|
57
|
-
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("
|
|
56
|
+
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("广播通知群组").default([]),
|
|
58
57
|
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60)
|
|
59
58
|
}).description("通知设置").collapse(),
|
|
60
59
|
// 权限管理组
|
|
@@ -278,21 +277,13 @@ function apply(ctx, config) {
|
|
|
278
277
|
}, {
|
|
279
278
|
primary: ["handle", "itemId"]
|
|
280
279
|
});
|
|
281
|
-
|
|
282
|
-
"
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
// 确保结构兼容性
|
|
289
|
-
price: 0,
|
|
290
|
-
damage: 0,
|
|
291
|
-
// 若需要可补充伤害值
|
|
292
|
-
tagEffects: {}
|
|
293
|
-
// 若无属性加成则留空
|
|
294
|
-
}
|
|
295
|
-
};
|
|
280
|
+
ctx.model.extend("ggcevo_tech", {
|
|
281
|
+
handle: "string",
|
|
282
|
+
techId: "unsigned",
|
|
283
|
+
level: "unsigned"
|
|
284
|
+
}, {
|
|
285
|
+
primary: ["handle", "techId"]
|
|
286
|
+
});
|
|
296
287
|
const weaponConfig = {
|
|
297
288
|
// 武器配置
|
|
298
289
|
"高斯步枪": {
|
|
@@ -305,8 +296,7 @@ function apply(ctx, config) {
|
|
|
305
296
|
tagEffects: {
|
|
306
297
|
"轻甲": 1.5
|
|
307
298
|
// 对轻甲目标造成150%伤害
|
|
308
|
-
}
|
|
309
|
-
effects: ""
|
|
299
|
+
}
|
|
310
300
|
},
|
|
311
301
|
"激光步枪": {
|
|
312
302
|
id: 2,
|
|
@@ -319,8 +309,7 @@ function apply(ctx, config) {
|
|
|
319
309
|
"重甲": 1.5,
|
|
320
310
|
// 对重甲目标造成150%伤害
|
|
321
311
|
"护盾": 0.5
|
|
322
|
-
}
|
|
323
|
-
effects: ""
|
|
312
|
+
}
|
|
324
313
|
},
|
|
325
314
|
"焚烧枪": {
|
|
326
315
|
id: 3,
|
|
@@ -333,8 +322,7 @@ function apply(ctx, config) {
|
|
|
333
322
|
"惧热": 2,
|
|
334
323
|
"生物": 1.5,
|
|
335
324
|
"护盾": 0.5
|
|
336
|
-
}
|
|
337
|
-
effects: ""
|
|
325
|
+
}
|
|
338
326
|
},
|
|
339
327
|
"碎骨步枪": {
|
|
340
328
|
id: 4,
|
|
@@ -347,8 +335,7 @@ function apply(ctx, config) {
|
|
|
347
335
|
"重甲": 2,
|
|
348
336
|
"机械": 0.5,
|
|
349
337
|
"护盾": 0.2
|
|
350
|
-
}
|
|
351
|
-
effects: ""
|
|
338
|
+
}
|
|
352
339
|
},
|
|
353
340
|
"等离子切割机": {
|
|
354
341
|
id: 5,
|
|
@@ -361,8 +348,7 @@ function apply(ctx, config) {
|
|
|
361
348
|
"重甲": 1.5,
|
|
362
349
|
"建筑": 1.5,
|
|
363
350
|
"机械": 1.2
|
|
364
|
-
}
|
|
365
|
-
effects: ""
|
|
351
|
+
}
|
|
366
352
|
},
|
|
367
353
|
"突击霰弹枪": {
|
|
368
354
|
id: 6,
|
|
@@ -374,8 +360,7 @@ function apply(ctx, config) {
|
|
|
374
360
|
tagEffects: {
|
|
375
361
|
"轻甲": 1.5,
|
|
376
362
|
"重甲": 0.8
|
|
377
|
-
}
|
|
378
|
-
effects: ""
|
|
363
|
+
}
|
|
379
364
|
},
|
|
380
365
|
"侦查步枪": {
|
|
381
366
|
id: 7,
|
|
@@ -388,8 +373,7 @@ function apply(ctx, config) {
|
|
|
388
373
|
"护盾": 0.5,
|
|
389
374
|
"轻甲": 0.5,
|
|
390
375
|
"重甲": 0.2
|
|
391
|
-
}
|
|
392
|
-
effects: ""
|
|
376
|
+
}
|
|
393
377
|
},
|
|
394
378
|
"零度之下": {
|
|
395
379
|
id: 8,
|
|
@@ -401,8 +385,7 @@ function apply(ctx, config) {
|
|
|
401
385
|
tagEffects: {
|
|
402
386
|
"惧寒": 2,
|
|
403
387
|
"灵能": 1.5
|
|
404
|
-
}
|
|
405
|
-
effects: ""
|
|
388
|
+
}
|
|
406
389
|
},
|
|
407
390
|
"弧焊枪": {
|
|
408
391
|
id: 9,
|
|
@@ -414,10 +397,26 @@ function apply(ctx, config) {
|
|
|
414
397
|
tagEffects: {
|
|
415
398
|
"建筑": 2,
|
|
416
399
|
"机械": 1.5
|
|
417
|
-
}
|
|
418
|
-
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
const SyndicatedItems = {
|
|
404
|
+
"E-2能量炸弹": {
|
|
405
|
+
id: 1,
|
|
406
|
+
type: "爆破物",
|
|
407
|
+
description: "一种小型的机械装置,用于吸收空间站能量并进行爆破",
|
|
408
|
+
price: 0,
|
|
409
|
+
redCrystalCost: 30,
|
|
410
|
+
effects: "当主宰为“空间站感染虫”时才能使用,对“空间站哨枪塔”造成其当前血量值的伤害(获得等同于伤害值的金币)"
|
|
419
411
|
},
|
|
420
|
-
|
|
412
|
+
"闪光弹": {
|
|
413
|
+
id: 2,
|
|
414
|
+
type: "手榴弹",
|
|
415
|
+
description: "非致命军用炸药",
|
|
416
|
+
price: 75,
|
|
417
|
+
redCrystalCost: 0,
|
|
418
|
+
effects: "对目标使用后,清空其累计技能计数"
|
|
419
|
+
}
|
|
421
420
|
};
|
|
422
421
|
const modConfig = {
|
|
423
422
|
"动能增幅": {
|
|
@@ -502,6 +501,8 @@ function apply(ctx, config) {
|
|
|
502
501
|
}
|
|
503
502
|
]
|
|
504
503
|
};
|
|
504
|
+
const asBossTags = /* @__PURE__ */ __name((arr) => arr, "asBossTags");
|
|
505
|
+
const asPassives = /* @__PURE__ */ __name((arr) => arr, "asPassives");
|
|
505
506
|
const passiveConfig = {
|
|
506
507
|
"弱化形态": {
|
|
507
508
|
effect: 0.1,
|
|
@@ -572,107 +573,98 @@ function apply(ctx, config) {
|
|
|
572
573
|
description: "拥有结构装甲,受到的伤害-20%; 若伤害来源于热能武器,则受到的伤害-40%"
|
|
573
574
|
}
|
|
574
575
|
};
|
|
576
|
+
const defineBoss = /* @__PURE__ */ __name((config2) => config2, "defineBoss");
|
|
575
577
|
const bossPool = [
|
|
576
|
-
{
|
|
578
|
+
defineBoss({
|
|
577
579
|
main: {
|
|
578
580
|
id: 1,
|
|
579
581
|
name: "异齿猛兽-首领",
|
|
580
582
|
type: "主宰",
|
|
581
|
-
maxHP:
|
|
582
|
-
tags: ["重甲", "生物", "异形"],
|
|
583
|
-
passive: ["异形甲壳"]
|
|
584
|
-
// 明确类型
|
|
583
|
+
maxHP: 15e3,
|
|
584
|
+
tags: asBossTags(["重甲", "生物", "异形"]),
|
|
585
|
+
passive: asPassives(["异形甲壳"])
|
|
585
586
|
},
|
|
586
587
|
minions: [
|
|
587
588
|
{
|
|
588
589
|
name: "异齿猛兽",
|
|
589
590
|
type: "子代",
|
|
590
|
-
maxHP:
|
|
591
|
-
tags: ["重甲", "生物", "异形"],
|
|
592
|
-
passive: ["弱化形态", "异形甲壳"]
|
|
593
|
-
// 明确类型
|
|
591
|
+
maxHP: 7500,
|
|
592
|
+
tags: asBossTags(["重甲", "生物", "异形"]),
|
|
593
|
+
passive: asPassives(["弱化形态", "异形甲壳"])
|
|
594
594
|
}
|
|
595
595
|
]
|
|
596
|
-
},
|
|
597
|
-
{
|
|
596
|
+
}),
|
|
597
|
+
defineBoss({
|
|
598
598
|
main: {
|
|
599
599
|
id: 2,
|
|
600
600
|
name: "寒冰王蛇",
|
|
601
601
|
type: "主宰",
|
|
602
602
|
maxHP: 1e4,
|
|
603
|
-
tags: ["重甲", "惧热", "生物", "异形"],
|
|
604
|
-
passive: ["冰霜环绕", "冰霜进化"]
|
|
605
|
-
// 明确类型
|
|
603
|
+
tags: asBossTags(["重甲", "惧热", "生物", "异形"]),
|
|
604
|
+
passive: asPassives(["冰霜环绕", "冰霜进化"])
|
|
606
605
|
},
|
|
607
606
|
minions: [
|
|
608
607
|
{
|
|
609
608
|
name: "冰蛇",
|
|
610
609
|
type: "子代",
|
|
611
610
|
maxHP: 3e3,
|
|
612
|
-
tags: ["惧热", "生物", "异形"],
|
|
613
|
-
passive: ["弱化形态", "冰霜回复", "冰霜进化"]
|
|
614
|
-
// 明确类型
|
|
611
|
+
tags: asBossTags(["惧热", "生物", "异形"]),
|
|
612
|
+
passive: asPassives(["弱化形态", "冰霜回复", "冰霜进化"])
|
|
615
613
|
}
|
|
616
614
|
]
|
|
617
|
-
},
|
|
618
|
-
{
|
|
615
|
+
}),
|
|
616
|
+
defineBoss({
|
|
619
617
|
main: {
|
|
620
618
|
id: 3,
|
|
621
619
|
name: "莽兽",
|
|
622
620
|
type: "主宰",
|
|
623
621
|
maxHP: 1e4,
|
|
624
|
-
tags: ["重甲", "生物", "异形"],
|
|
625
|
-
passive: ["应激甲壳II", "求生本能II", "冷适应"]
|
|
626
|
-
// 明确类型
|
|
622
|
+
tags: asBossTags(["重甲", "生物", "异形"]),
|
|
623
|
+
passive: asPassives(["应激甲壳II", "求生本能II", "冷适应"])
|
|
627
624
|
},
|
|
628
625
|
minions: [
|
|
629
626
|
{
|
|
630
627
|
name: "狂暴畸变体",
|
|
631
628
|
type: "子代",
|
|
632
629
|
maxHP: 3e3,
|
|
633
|
-
tags: ["重甲", "生物", "异形"],
|
|
634
|
-
passive: ["弱化形态", "应激甲壳I", "求生本能I", "冷适应"]
|
|
635
|
-
// 明确类型
|
|
630
|
+
tags: asBossTags(["重甲", "生物", "异形"]),
|
|
631
|
+
passive: asPassives(["弱化形态", "应激甲壳I", "求生本能I", "冷适应"])
|
|
636
632
|
},
|
|
637
633
|
{
|
|
638
634
|
name: "剧毒畸变体",
|
|
639
635
|
type: "子代",
|
|
640
636
|
maxHP: 3e3,
|
|
641
|
-
tags: ["重甲", "生物", "异形"],
|
|
642
|
-
passive: ["弱化形态", "应激甲壳I", "求生本能I", "冷适应"]
|
|
643
|
-
// 明确类型
|
|
637
|
+
tags: asBossTags(["重甲", "生物", "异形"]),
|
|
638
|
+
passive: asPassives(["弱化形态", "应激甲壳I", "求生本能I", "冷适应"])
|
|
644
639
|
}
|
|
645
640
|
]
|
|
646
|
-
},
|
|
647
|
-
{
|
|
641
|
+
}),
|
|
642
|
+
defineBoss({
|
|
648
643
|
main: {
|
|
649
644
|
id: 4,
|
|
650
645
|
name: "空间站感染虫",
|
|
651
646
|
type: "主宰",
|
|
652
647
|
maxHP: 1e4,
|
|
653
|
-
tags: ["重甲", "生物", "机械", "异形"],
|
|
654
|
-
passive: ["感染空间站", "病毒云", "霉菌滋生"]
|
|
655
|
-
// 明确类型
|
|
648
|
+
tags: asBossTags(["重甲", "生物", "机械", "异形"]),
|
|
649
|
+
passive: asPassives(["感染空间站", "病毒云", "霉菌滋生"])
|
|
656
650
|
},
|
|
657
651
|
minions: [
|
|
658
652
|
{
|
|
659
653
|
name: "机械感染虫",
|
|
660
654
|
type: "子代",
|
|
661
655
|
maxHP: 3e3,
|
|
662
|
-
tags: ["重甲", "生物", "机械", "异形"],
|
|
663
|
-
passive: ["弱化形态", "病毒云", "霉菌滋生"]
|
|
664
|
-
// 明确类型
|
|
656
|
+
tags: asBossTags(["重甲", "生物", "机械", "异形"]),
|
|
657
|
+
passive: asPassives(["弱化形态", "病毒云", "霉菌滋生"])
|
|
665
658
|
},
|
|
666
659
|
{
|
|
667
660
|
name: "空间站哨枪塔",
|
|
668
661
|
type: "子代",
|
|
669
662
|
maxHP: 5e3,
|
|
670
|
-
tags: ["重甲", "机械", "建筑"],
|
|
671
|
-
passive: ["岗哨机枪", "结构装甲"]
|
|
672
|
-
// 明确类型
|
|
663
|
+
tags: asBossTags(["重甲", "机械", "建筑"]),
|
|
664
|
+
passive: asPassives(["岗哨机枪", "结构装甲"])
|
|
673
665
|
}
|
|
674
666
|
]
|
|
675
|
-
}
|
|
667
|
+
})
|
|
676
668
|
];
|
|
677
669
|
const spaceStationCrewConfig = [
|
|
678
670
|
{
|
|
@@ -712,7 +704,7 @@ function apply(ctx, config) {
|
|
|
712
704
|
},
|
|
713
705
|
{
|
|
714
706
|
professionName: "情报副官",
|
|
715
|
-
effect: "
|
|
707
|
+
effect: "",
|
|
716
708
|
requirements: "拥有500枚金币",
|
|
717
709
|
Jobtransfer: false,
|
|
718
710
|
costcoins: 3e3
|
|
@@ -750,7 +742,7 @@ function apply(ctx, config) {
|
|
|
750
742
|
{
|
|
751
743
|
professionName: "能量武器专家",
|
|
752
744
|
effect: "能量武器攻击伤害+20%,解锁MK-4激光步枪(传奇)购买权限",
|
|
753
|
-
requirements: "
|
|
745
|
+
requirements: "拥有一把3级及以上等级的能量武器",
|
|
754
746
|
Jobtransfer: true,
|
|
755
747
|
costcoins: 0,
|
|
756
748
|
costredcrystal: 20
|
|
@@ -765,7 +757,7 @@ function apply(ctx, config) {
|
|
|
765
757
|
},
|
|
766
758
|
{
|
|
767
759
|
professionName: "枪手",
|
|
768
|
-
effect: "武器等级上限为7
|
|
760
|
+
effect: "武器等级上限为7级",
|
|
769
761
|
requirements: "拥有2把武器等级为6的武器",
|
|
770
762
|
Jobtransfer: false,
|
|
771
763
|
costcoins: 0,
|
|
@@ -781,9 +773,9 @@ function apply(ctx, config) {
|
|
|
781
773
|
},
|
|
782
774
|
{
|
|
783
775
|
professionName: "纵火狂",
|
|
784
|
-
effect: "热能武器攻击伤害+
|
|
785
|
-
requirements: "",
|
|
786
|
-
Jobtransfer:
|
|
776
|
+
effect: "热能武器攻击伤害+20%,解锁龙息散弹枪(传奇)购买权限",
|
|
777
|
+
requirements: "拥有一把3级及以上等级的热能武器",
|
|
778
|
+
Jobtransfer: true,
|
|
787
779
|
costcoins: 0,
|
|
788
780
|
costredcrystal: 20
|
|
789
781
|
},
|
|
@@ -844,6 +836,86 @@ function apply(ctx, config) {
|
|
|
844
836
|
costredcrystal: 0
|
|
845
837
|
}
|
|
846
838
|
];
|
|
839
|
+
const Spacestationtechnology = [
|
|
840
|
+
{
|
|
841
|
+
techId: 1,
|
|
842
|
+
techname: "采掘系统",
|
|
843
|
+
careerNames: ["深空矿工", "情报副官"],
|
|
844
|
+
// 新增职业名称字段
|
|
845
|
+
maxLevel: 5,
|
|
846
|
+
levels: [
|
|
847
|
+
{
|
|
848
|
+
level: 1,
|
|
849
|
+
cost: 500,
|
|
850
|
+
description: "提高挖矿效率,每日签到金币奖励+5%",
|
|
851
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+10%"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
level: 2,
|
|
855
|
+
cost: 1750,
|
|
856
|
+
description: "提高挖矿效率,每日签到金币奖励+10%",
|
|
857
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+20%,解锁专属“挖矿”权限"
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
level: 3,
|
|
861
|
+
cost: 2950,
|
|
862
|
+
description: "提高挖矿效率,每日签到金币奖励+15%",
|
|
863
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+30%,解锁专属“挖矿”权限,并且挖矿效率提高10%"
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
level: 4,
|
|
867
|
+
cost: 4250,
|
|
868
|
+
description: "提高挖矿效率,每日签到金币奖励+20%",
|
|
869
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+40%,解锁专属“挖矿”权限,并且挖矿效率提高20%"
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
level: 5,
|
|
873
|
+
cost: 5375,
|
|
874
|
+
description: "提高挖矿效率,每日签到金币奖励+25%",
|
|
875
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+50%,解锁专属“挖矿”权限,并且挖矿效率提高30%"
|
|
876
|
+
}
|
|
877
|
+
]
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
techId: 2,
|
|
881
|
+
techname: "武器系统",
|
|
882
|
+
careerNames: ["武器中士", "情报副官"],
|
|
883
|
+
// 新增职业名称字段
|
|
884
|
+
maxLevel: 5,
|
|
885
|
+
levels: [
|
|
886
|
+
{
|
|
887
|
+
level: 1,
|
|
888
|
+
cost: 500,
|
|
889
|
+
description: "提升空间站武器等级,升级武器享有5%的折扣",
|
|
890
|
+
careerBonus: "武器中士/情报副官: 升级武器享有10%的折扣"
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
level: 2,
|
|
894
|
+
cost: 1500,
|
|
895
|
+
description: "提升空间站武器等级,升级武器享有10%的折扣",
|
|
896
|
+
careerBonus: "武器中士/情报副官: 升级武器享有20%的折扣,购买武器享有10%的折扣(非传奇)"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
level: 3,
|
|
900
|
+
cost: 2550,
|
|
901
|
+
description: "提升空间站武器等级,升级武器享有15%的折扣",
|
|
902
|
+
careerBonus: "武器中士/情报副官: 升级武器享有30%的折扣,购买武器享有15%的折扣(非传奇)"
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
level: 4,
|
|
906
|
+
cost: 3950,
|
|
907
|
+
description: "提升空间站武器等级,升级武器享有20%的折扣",
|
|
908
|
+
careerBonus: "武器中士/情报副官: 在升级武器享有40%的折扣,购买武器享有20%的折扣(非传奇)"
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
level: 5,
|
|
912
|
+
cost: 4650,
|
|
913
|
+
description: "提升空间站武器等级,升级武器享有25%的折扣,可以以原价购买传奇武器(仅限一把)",
|
|
914
|
+
careerBonus: "武器中士/情报副官: 升级武器享有50%的折扣,购买武器享有25%的折扣(非传奇),可以以80%的价格购买传奇武器(仅限一把)"
|
|
915
|
+
}
|
|
916
|
+
]
|
|
917
|
+
}
|
|
918
|
+
];
|
|
847
919
|
function calculateModifiers(equippedWeapon, weaponName, hasCritRhythm) {
|
|
848
920
|
let totalModAdd = 0;
|
|
849
921
|
let hasCrit = false;
|
|
@@ -872,31 +944,25 @@ function apply(ctx, config) {
|
|
|
872
944
|
return { totalModAdd, hasCrit };
|
|
873
945
|
}
|
|
874
946
|
__name(calculateModifiers, "calculateModifiers");
|
|
875
|
-
async function calculateTagMultiplier(weaponData,
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
const bossTags = Array.isArray(bossRecord[0].tags) ? bossRecord[0].tags : JSON.parse(bossRecord[0].tags || "[]");
|
|
947
|
+
async function calculateTagMultiplier(weaponData, tags, equippedWeapon) {
|
|
948
|
+
const MOD_EFFECTS = [
|
|
949
|
+
{ mod: "裂甲核心", tag: "重甲", value: 1.2 },
|
|
950
|
+
{ mod: "助燃核心", tag: "惧热", value: 4 }
|
|
951
|
+
];
|
|
881
952
|
let totalAdditive = 0;
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
effectValue = 4;
|
|
888
|
-
} else {
|
|
889
|
-
effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
890
|
-
}
|
|
953
|
+
for (const tag of tags) {
|
|
954
|
+
const activeMod = MOD_EFFECTS.find(
|
|
955
|
+
(me) => me.tag === tag && equippedWeapon.installedMods?.includes(me.mod)
|
|
956
|
+
);
|
|
957
|
+
const effectValue = activeMod ? activeMod.value : weaponData.tagEffects?.[tag] ?? 1;
|
|
891
958
|
totalAdditive += effectValue - 1;
|
|
892
|
-
}
|
|
959
|
+
}
|
|
893
960
|
return totalAdditive;
|
|
894
961
|
}
|
|
895
962
|
__name(calculateTagMultiplier, "calculateTagMultiplier");
|
|
896
|
-
function calculatePassiveEffects(
|
|
963
|
+
function calculatePassiveEffects(passives) {
|
|
897
964
|
let passiveEffect = 0;
|
|
898
|
-
|
|
899
|
-
effectivePassives.forEach((passive) => {
|
|
965
|
+
passives.forEach((passive) => {
|
|
900
966
|
const effect = passiveConfig[passive]?.effect || 0;
|
|
901
967
|
passiveEffect += effect;
|
|
902
968
|
});
|
|
@@ -924,6 +990,14 @@ function apply(ctx, config) {
|
|
|
924
990
|
message = "⚠️ 能量武器专家:未装备能量武器,加成未生效";
|
|
925
991
|
}
|
|
926
992
|
}
|
|
993
|
+
if (faction === "辛迪加海盗" && career === "纵火狂") {
|
|
994
|
+
if (weaponType === "热能武器") {
|
|
995
|
+
multiplier *= 1.2;
|
|
996
|
+
message = "⚡ 职业加成:纵火狂(热能武器伤害+20%)";
|
|
997
|
+
} else {
|
|
998
|
+
message = "⚠️ 纵火狂:未装备热能武器,加成未生效";
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
927
1001
|
return {
|
|
928
1002
|
damage: currentDamage * multiplier,
|
|
929
1003
|
message: message || void 0
|
|
@@ -935,8 +1009,10 @@ function apply(ctx, config) {
|
|
|
935
1009
|
return Math.floor(rankRecord.rank / 400) * 0.01;
|
|
936
1010
|
}
|
|
937
1011
|
__name(calculateRankBonus, "calculateRankBonus");
|
|
938
|
-
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss) {
|
|
1012
|
+
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss, options) {
|
|
939
1013
|
let effectMessage = [];
|
|
1014
|
+
const finalTags = options?.customTags || targetBoss.tags || [];
|
|
1015
|
+
const finalPassives = options?.customPassives || targetBoss.skills || [];
|
|
940
1016
|
const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
|
|
941
1017
|
const { regionId, realmId, profileId } = profile;
|
|
942
1018
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -959,10 +1035,9 @@ function apply(ctx, config) {
|
|
|
959
1035
|
if (critRhythmEffect) {
|
|
960
1036
|
effectMessage.push("🎵 暴击韵律祈愿生效(暴击率+20%)");
|
|
961
1037
|
}
|
|
962
|
-
const
|
|
963
|
-
const tagMultiplier = await calculateTagMultiplier(weaponData, targetBossConfig, equippedWeapon);
|
|
1038
|
+
const tagMultiplier = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
|
|
964
1039
|
damage *= 1 + tagMultiplier;
|
|
965
|
-
const passiveMultiplier = calculatePassiveEffects(
|
|
1040
|
+
const passiveMultiplier = calculatePassiveEffects(finalPassives);
|
|
966
1041
|
damage *= 1 + passiveMultiplier;
|
|
967
1042
|
const { damage: careerDamage, message: careerMessage } = await calculateCareerBonus(
|
|
968
1043
|
ctx2,
|
|
@@ -1692,6 +1767,10 @@ function apply(ctx, config) {
|
|
|
1692
1767
|
const damageRecords = await ctx2.database.get("ggcevo_boss_damage", { handle });
|
|
1693
1768
|
const totalAttack = damageRecords.reduce((sum, r) => sum + r.attackCount, 0);
|
|
1694
1769
|
const totalDamage = damageRecords.reduce((sum, r) => sum + r.totalDamage, 0);
|
|
1770
|
+
const weapons = await ctx2.database.get("ggcevo_equipment", {
|
|
1771
|
+
handle,
|
|
1772
|
+
level: { $gte: 3 }
|
|
1773
|
+
});
|
|
1695
1774
|
switch (profession) {
|
|
1696
1775
|
case "深空矿工":
|
|
1697
1776
|
return {
|
|
@@ -1726,17 +1805,22 @@ function apply(ctx, config) {
|
|
|
1726
1805
|
message: `需要累计造成300伤害(当前${totalDamage})`
|
|
1727
1806
|
};
|
|
1728
1807
|
case "能量武器专家":
|
|
1729
|
-
const weapons = await ctx2.database.get("ggcevo_equipment", {
|
|
1730
|
-
handle,
|
|
1731
|
-
level: { $gte: 3 }
|
|
1732
|
-
});
|
|
1733
1808
|
const hasEnergyWeapon = weapons.some((weapon) => {
|
|
1734
1809
|
const weaponConfigEntry = Object.values(weaponConfig).find((c) => c.id === weapon.weaponId);
|
|
1735
1810
|
return weaponConfigEntry?.type === "能量武器";
|
|
1736
1811
|
});
|
|
1737
1812
|
return {
|
|
1738
1813
|
success: hasEnergyWeapon,
|
|
1739
|
-
message:
|
|
1814
|
+
message: `需要拥有一把3级及以上等级的能量武器`
|
|
1815
|
+
};
|
|
1816
|
+
case "纵火狂":
|
|
1817
|
+
const hasthermalWeapon = weapons.some((weapon) => {
|
|
1818
|
+
const weaponConfigEntry = Object.values(weaponConfig).find((c) => c.id === weapon.weaponId);
|
|
1819
|
+
return weaponConfigEntry?.type === "热能武器";
|
|
1820
|
+
});
|
|
1821
|
+
return {
|
|
1822
|
+
success: hasthermalWeapon,
|
|
1823
|
+
message: `需要拥有一把3级及以上等级的热能武器`
|
|
1740
1824
|
};
|
|
1741
1825
|
case "清洁工":
|
|
1742
1826
|
if (!mainBoss) return { success: false, message: "当前暂无伤害榜。" };
|
|
@@ -1758,36 +1842,201 @@ function apply(ctx, config) {
|
|
|
1758
1842
|
}
|
|
1759
1843
|
}
|
|
1760
1844
|
__name(checkTransferRequirements, "checkTransferRequirements");
|
|
1761
|
-
async function applyItemEffect(session, handle,
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1845
|
+
async function applyItemEffect(session, handle, itemConfig2, target) {
|
|
1846
|
+
try {
|
|
1847
|
+
const itemName = Object.entries(SyndicatedItems).find(
|
|
1848
|
+
([_, item]) => item.id === itemConfig2.id
|
|
1849
|
+
)?.[0] || "未知物品";
|
|
1850
|
+
if (itemConfig2.id === 1) {
|
|
1851
|
+
const activeSentry = await ctx.database.get("ggcevo_boss", {
|
|
1852
|
+
name: "空间站哨枪塔",
|
|
1853
|
+
isActive: true
|
|
1854
|
+
});
|
|
1855
|
+
if (!activeSentry.length) return {
|
|
1856
|
+
success: false,
|
|
1857
|
+
message: "⚠️ 目标「空间站哨枪塔」未激活"
|
|
1858
|
+
};
|
|
1859
|
+
const [SentryTower] = await ctx.database.get("ggcevo_boss", {
|
|
1860
|
+
name: "空间站哨枪塔",
|
|
1861
|
+
isActive: true
|
|
1862
|
+
});
|
|
1863
|
+
const damageValue = SentryTower.HP;
|
|
1864
|
+
await ctx.database.set(
|
|
1865
|
+
"ggcevo_boss",
|
|
1866
|
+
{ name: "空间站哨枪塔" },
|
|
1867
|
+
{ isActive: false, HP: 0 }
|
|
1868
|
+
);
|
|
1869
|
+
await ctx.database.withTransaction(async () => {
|
|
1870
|
+
const signRecords = await ctx.database.get("ggcevo_sign", { handle });
|
|
1871
|
+
await ctx.database.upsert("ggcevo_sign", [{
|
|
1872
|
+
handle,
|
|
1873
|
+
totalRewards: (signRecords[0]?.totalRewards || 0) + damageValue
|
|
1874
|
+
}], ["handle"]);
|
|
1875
|
+
const damageRecords = await ctx.database.get("ggcevo_boss_damage", { handle });
|
|
1876
|
+
await ctx.database.upsert("ggcevo_boss_damage", [{
|
|
1877
|
+
handle,
|
|
1878
|
+
playerName: session.username,
|
|
1879
|
+
totalDamage: (damageRecords[0]?.totalDamage || 0) + damageValue,
|
|
1880
|
+
attackCount: damageRecords[0]?.attackCount || 0,
|
|
1881
|
+
bossGroupId: 4
|
|
1882
|
+
}], ["handle"]);
|
|
1883
|
+
});
|
|
1884
|
+
return {
|
|
1885
|
+
success: true,
|
|
1886
|
+
message: `成功引爆${itemName},造成 ${damageValue} 点伤害,获得等额金币`
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1889
|
+
if (itemConfig2.id === 2) {
|
|
1890
|
+
if (!target) return {
|
|
1891
|
+
success: false,
|
|
1892
|
+
message: "该武器使用需要选择合适的目标。"
|
|
1893
|
+
};
|
|
1894
|
+
const targetboss = await ctx.database.get("ggcevo_boss", {
|
|
1895
|
+
name: target,
|
|
1896
|
+
isActive: true
|
|
1897
|
+
});
|
|
1898
|
+
if (!targetboss.length || targetboss[0].Skillcountpoints === 0) return {
|
|
1899
|
+
success: false,
|
|
1900
|
+
message: "您选择的不是合法目标(目标未存活/目标无技能计数)。"
|
|
1901
|
+
};
|
|
1902
|
+
await ctx.database.set(
|
|
1903
|
+
"ggcevo_boss",
|
|
1904
|
+
{ name: target },
|
|
1905
|
+
{ Skillcountpoints: 0 }
|
|
1906
|
+
);
|
|
1907
|
+
return {
|
|
1908
|
+
success: true,
|
|
1909
|
+
message: `成功使用${itemName},您的目标${target}已重置其技能计数`
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
return {
|
|
1913
|
+
success: true,
|
|
1914
|
+
message: `${itemName} 效果已生效(开发中)`
|
|
1915
|
+
};
|
|
1916
|
+
} catch (error) {
|
|
1917
|
+
console.error("物品效果处理失败:", error);
|
|
1918
|
+
return {
|
|
1919
|
+
success: false,
|
|
1920
|
+
message: "⚠️ 物品效果处理异常,已回滚操作"
|
|
1921
|
+
};
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
__name(applyItemEffect, "applyItemEffect");
|
|
1925
|
+
async function handleTechUpgrade(handle, target) {
|
|
1926
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
1927
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
1928
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
1929
|
+
}
|
|
1930
|
+
const tech = Spacestationtechnology.find(
|
|
1931
|
+
(t) => t.techname === target || t.techId == target
|
|
1932
|
+
);
|
|
1933
|
+
const [techEntry] = await ctx.database.get("ggcevo_tech", { handle, techId: tech.techId });
|
|
1934
|
+
const currentLevel = techEntry?.level || 0;
|
|
1935
|
+
if (currentLevel >= tech.maxLevel) return `❌ ${tech.techname}已达最高等级`;
|
|
1936
|
+
const nextLevel = currentLevel + 1;
|
|
1937
|
+
const levelData = tech.levels.find((l) => l.level === nextLevel);
|
|
1938
|
+
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1939
|
+
if (signInfo?.totalRewards < levelData.cost) {
|
|
1940
|
+
return `❌ 需要 ${levelData.cost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
1941
|
+
}
|
|
1942
|
+
await ctx.database.withTransaction(async () => {
|
|
1943
|
+
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
1944
|
+
totalRewards: signInfo.totalRewards - levelData.cost
|
|
1945
|
+
});
|
|
1946
|
+
await ctx.database.upsert("ggcevo_tech", [{
|
|
1947
|
+
handle,
|
|
1948
|
+
techId: tech.techId,
|
|
1949
|
+
level: nextLevel
|
|
1950
|
+
}], ["handle", "techId"]);
|
|
1951
|
+
});
|
|
1952
|
+
return `✅ ${tech.techname} 升级至 Lv.${nextLevel}
|
|
1953
|
+
📝 ${levelData.description}
|
|
1954
|
+
💼 ${levelData.careerBonus}`;
|
|
1955
|
+
}
|
|
1956
|
+
__name(handleTechUpgrade, "handleTechUpgrade");
|
|
1957
|
+
async function handleWeaponUpgrade(handle, target) {
|
|
1958
|
+
const weaponData = weaponConfig[target];
|
|
1959
|
+
const [equipment] = await ctx.database.get("ggcevo_equipment", {
|
|
1960
|
+
handle,
|
|
1961
|
+
weaponId: weaponData.id
|
|
1962
|
+
});
|
|
1963
|
+
if (!equipment) return "❌ 尚未获得该武器";
|
|
1964
|
+
if (equipment.level >= 6) return "❌ 武器已达最高等级";
|
|
1965
|
+
const BASE_COST = [1050, 1450, 1850, 2250, 2650, 3050];
|
|
1966
|
+
const baseCost = BASE_COST[equipment.level];
|
|
1967
|
+
const weaponTechConfig = Spacestationtechnology.find((t) => t.techId === 2);
|
|
1968
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
1969
|
+
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 }).catch(() => [{ level: 0 }]);
|
|
1970
|
+
const techLevel = Math.min(Math.max(weaponTech?.level || 0, 0), 5);
|
|
1971
|
+
const isCareerMatch = weaponTechConfig?.careerNames.includes(careerData?.career);
|
|
1972
|
+
const BASE_DISCOUNTS = [5, 10, 15, 20, 25];
|
|
1973
|
+
const CAREER_DISCOUNTS = [10, 20, 30, 40, 50];
|
|
1974
|
+
const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
|
|
1975
|
+
const careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
|
|
1976
|
+
const weaponDiscount = Math.max(baseDiscount, careerDiscount) / 100;
|
|
1977
|
+
let discountedCost = baseCost * (1 - weaponDiscount);
|
|
1978
|
+
const activeWish = await checkFoxBlessing(handle);
|
|
1979
|
+
if (activeWish) {
|
|
1980
|
+
discountedCost *= 0.8;
|
|
1981
|
+
}
|
|
1982
|
+
const actualCost = Math.floor(discountedCost);
|
|
1983
|
+
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1984
|
+
if (signInfo?.totalRewards < actualCost) {
|
|
1985
|
+
return `❌ 需要 ${actualCost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
1986
|
+
}
|
|
1987
|
+
await ctx.database.withTransaction(async () => {
|
|
1988
|
+
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
1989
|
+
totalRewards: signInfo.totalRewards - actualCost
|
|
1990
|
+
});
|
|
1768
1991
|
await ctx.database.set(
|
|
1769
|
-
"
|
|
1770
|
-
{
|
|
1992
|
+
"ggcevo_equipment",
|
|
1993
|
+
{ handle, weaponId: weaponData.id },
|
|
1771
1994
|
{
|
|
1772
|
-
|
|
1773
|
-
|
|
1995
|
+
level: equipment.level + 1,
|
|
1996
|
+
modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
|
|
1774
1997
|
}
|
|
1775
1998
|
);
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1999
|
+
if (activeWish) {
|
|
2000
|
+
await ctx.database.set(
|
|
2001
|
+
"ggcevo_Wish_Record",
|
|
2002
|
+
{ id: activeWish.id },
|
|
2003
|
+
{ isused: true }
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
});
|
|
2007
|
+
const newLevel = equipment.level + 1;
|
|
2008
|
+
const damage = (weaponData.damage * (1 + 0.1 * newLevel)).toFixed(1);
|
|
2009
|
+
let msg = `${target} 升级成功!Lv.${newLevel}`;
|
|
2010
|
+
msg += `
|
|
2011
|
+
💸 消耗:${actualCost}金币 (原价${baseCost})`;
|
|
2012
|
+
let discountDetails = [];
|
|
2013
|
+
if (weaponDiscount > 0) {
|
|
2014
|
+
discountDetails.push(`武器系统 Lv${techLevel} 折扣:${Math.max(baseDiscount, careerDiscount)}%`);
|
|
2015
|
+
}
|
|
2016
|
+
if (activeWish) {
|
|
2017
|
+
discountDetails.push("灵狐升运折扣:20%");
|
|
1788
2018
|
}
|
|
2019
|
+
if (discountDetails.length > 0) {
|
|
2020
|
+
msg += `
|
|
2021
|
+
🔧 已应用折扣:${discountDetails.join(" + ")}`;
|
|
2022
|
+
}
|
|
2023
|
+
msg += `
|
|
2024
|
+
💥 伤害:${damage}`;
|
|
2025
|
+
msg += `
|
|
2026
|
+
🔩 改装槽:${Math.floor(newLevel / 3) + 1}个`;
|
|
2027
|
+
return msg;
|
|
1789
2028
|
}
|
|
1790
|
-
__name(
|
|
2029
|
+
__name(handleWeaponUpgrade, "handleWeaponUpgrade");
|
|
2030
|
+
async function checkFoxBlessing(handle) {
|
|
2031
|
+
return ctx.database.get("ggcevo_Wish_Record", {
|
|
2032
|
+
handle,
|
|
2033
|
+
wishname: "灵狐升运",
|
|
2034
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
2035
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
2036
|
+
isused: false
|
|
2037
|
+
}).then((records) => records[0]);
|
|
2038
|
+
}
|
|
2039
|
+
__name(checkFoxBlessing, "checkFoxBlessing");
|
|
1791
2040
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
1792
2041
|
const session = argv.session;
|
|
1793
2042
|
let winCount = 0;
|
|
@@ -2015,17 +2264,41 @@ ${itemDetails.join("\n")}`;
|
|
|
2015
2264
|
}
|
|
2016
2265
|
let redCrystal = 0;
|
|
2017
2266
|
let careerCrystalMessage = "";
|
|
2018
|
-
if (meowEffect) {
|
|
2019
|
-
tickets *= 2;
|
|
2020
|
-
points *= 2;
|
|
2021
|
-
effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励!";
|
|
2022
|
-
}
|
|
2023
|
-
let careerMessage = "";
|
|
2024
2267
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
2268
|
+
let miningBonus = 0;
|
|
2269
|
+
let miningMessage = "";
|
|
2270
|
+
const BASE_BONUS = [5, 10, 15, 20, 25];
|
|
2271
|
+
const CAREER_BONUS = [10, 20, 30, 40, 50];
|
|
2272
|
+
const miningTechConfig = Spacestationtechnology.find((t) => t.techId === 1);
|
|
2273
|
+
if (miningTechConfig) {
|
|
2274
|
+
const [userMiningTech] = await ctx.database.get("ggcevo_tech", {
|
|
2275
|
+
handle,
|
|
2276
|
+
techId: 1
|
|
2277
|
+
}).catch(() => [{ level: 0 }]);
|
|
2278
|
+
const techLevel = Math.min(Math.max(userMiningTech?.level || 0, 0), 5);
|
|
2279
|
+
const baseBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
|
|
2280
|
+
let careerTechBonus = 0;
|
|
2281
|
+
if (careerData?.career && miningTechConfig.careerNames.includes(careerData.career)) {
|
|
2282
|
+
careerTechBonus = techLevel > 0 ? CAREER_BONUS[techLevel - 1] : 0;
|
|
2283
|
+
}
|
|
2284
|
+
miningBonus = Math.max(baseBonus, careerTechBonus);
|
|
2285
|
+
if (miningBonus > 0) {
|
|
2286
|
+
miningMessage = `
|
|
2287
|
+
⚙️ 采掘系统 Lv${techLevel} 金币加成:+${miningBonus}%`;
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
let minerBonus = 0;
|
|
2291
|
+
let minerMessage = "";
|
|
2025
2292
|
if (careerData?.career === "深空矿工") {
|
|
2026
|
-
|
|
2027
|
-
|
|
2293
|
+
minerBonus = 50;
|
|
2294
|
+
minerMessage = `
|
|
2295
|
+
⛏️ 深空矿工职业加成:金币+50%`;
|
|
2296
|
+
}
|
|
2297
|
+
const totalBonus = miningBonus + minerBonus;
|
|
2298
|
+
if (totalBonus > 0) {
|
|
2299
|
+
points = Math.round(points * (1 + totalBonus / 100));
|
|
2028
2300
|
}
|
|
2301
|
+
const bonusMessage = miningMessage + minerMessage;
|
|
2029
2302
|
if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
|
|
2030
2303
|
if (monthlyDays < 7) {
|
|
2031
2304
|
redCrystal = 1;
|
|
@@ -2041,6 +2314,11 @@ ${itemDetails.join("\n")}`;
|
|
|
2041
2314
|
careerCrystalMessage = `
|
|
2042
2315
|
⚓ 辛迪加财务经理职业加成:获得 ${redCrystal} 红晶`;
|
|
2043
2316
|
}
|
|
2317
|
+
if (meowEffect) {
|
|
2318
|
+
tickets *= 2;
|
|
2319
|
+
points *= 2;
|
|
2320
|
+
effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励(金币和咕咕币)!";
|
|
2321
|
+
}
|
|
2044
2322
|
await ctx.database.withTransaction(async () => {
|
|
2045
2323
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
2046
2324
|
handle,
|
|
@@ -2062,7 +2340,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2062
2340
|
});
|
|
2063
2341
|
return `签到成功!本月累计签到${monthlyDays}天,获得:
|
|
2064
2342
|
💰 金币 x ${points}
|
|
2065
|
-
🪙 咕咕币 x ${tickets}` + effectMessage +
|
|
2343
|
+
🪙 咕咕币 x ${tickets}` + (effectMessage || "") + bonusMessage + (careerCrystalMessage || "");
|
|
2066
2344
|
} catch (error) {
|
|
2067
2345
|
console.error("签到命令时发生错误:", error);
|
|
2068
2346
|
return "服务器繁忙,请稍后尝试。";
|
|
@@ -2322,7 +2600,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2322
2600
|
ctx.setInterval(async () => {
|
|
2323
2601
|
if (config.autorank) {
|
|
2324
2602
|
try {
|
|
2325
|
-
const ggcmap = await ctx.database.get("sc2arcade_map", {
|
|
2603
|
+
const ggcmap = await ctx.database.get("sc2arcade_map", { regionId: 3, mapId: 165561 });
|
|
2326
2604
|
const lastdate = ggcmap[0].lastdate;
|
|
2327
2605
|
let currentMaxDate = new Date(lastdate);
|
|
2328
2606
|
let nextCursor = null;
|
|
@@ -2372,7 +2650,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2372
2650
|
} while (nextCursor && shouldContinue);
|
|
2373
2651
|
if (pageMaxDate > currentMaxDate) {
|
|
2374
2652
|
currentMaxDate = pageMaxDate;
|
|
2375
|
-
await ctx.database.set("sc2arcade_map", {
|
|
2653
|
+
await ctx.database.set("sc2arcade_map", { regionId: 3, mapId: 165561 }, {
|
|
2376
2654
|
lastdate: new Date(currentMaxDate.toISOString())
|
|
2377
2655
|
});
|
|
2378
2656
|
}
|
|
@@ -2383,7 +2661,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2383
2661
|
}, 60 * 60 * 1e3);
|
|
2384
2662
|
ctx.command("ggcevo/胜点榜数据同步", { authority: 3 }).action(async () => {
|
|
2385
2663
|
try {
|
|
2386
|
-
const ggcmap = await ctx.database.get("sc2arcade_map", {
|
|
2664
|
+
const ggcmap = await ctx.database.get("sc2arcade_map", { regionId: 3, mapId: 165561 });
|
|
2387
2665
|
const lastdate = ggcmap[0].lastdate;
|
|
2388
2666
|
let currentMaxDate = new Date(lastdate);
|
|
2389
2667
|
let nextCursor = null;
|
|
@@ -2433,7 +2711,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2433
2711
|
} while (nextCursor && shouldContinue);
|
|
2434
2712
|
if (pageMaxDate > currentMaxDate) {
|
|
2435
2713
|
currentMaxDate = pageMaxDate;
|
|
2436
|
-
await ctx.database.set("sc2arcade_map", {
|
|
2714
|
+
await ctx.database.set("sc2arcade_map", { regionId: 3, mapId: 165561 }, {
|
|
2437
2715
|
lastdate: new Date(currentMaxDate.toISOString())
|
|
2438
2716
|
});
|
|
2439
2717
|
}
|
|
@@ -2459,7 +2737,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2459
2737
|
displayName: await checkSensitiveWord(item.name) ? item.name : (item.name[0] || "") + "***"
|
|
2460
2738
|
}))
|
|
2461
2739
|
);
|
|
2462
|
-
const ggcmap = await ctx.database.get("sc2arcade_map", {
|
|
2740
|
+
const ggcmap = await ctx.database.get("sc2arcade_map", { regionId: 3, mapId: 165561 });
|
|
2463
2741
|
const lastdate = ggcmap[0].lastdate;
|
|
2464
2742
|
const rankingText = processedRecords.map(
|
|
2465
2743
|
(item, index) => `${offset + index + 1}. ${item.displayName} | 积分: ${item.rank} | 胜率: ${item.matches === 0 ? "0.00%" : (item.wins / item.matches * 100).toFixed(2) + "%"}`
|
|
@@ -3196,7 +3474,7 @@ ${achievementList.join("\n")}`;
|
|
|
3196
3474
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
3197
3475
|
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @指定pk玩家”。";
|
|
3198
3476
|
const targetUserId = parsedUser.attrs.id;
|
|
3199
|
-
const targetUsername = await session.bot.getGuildMember(
|
|
3477
|
+
const targetUsername = await session.bot.getGuildMember(session.guildId, targetUserId);
|
|
3200
3478
|
const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
|
|
3201
3479
|
if (!targetprofile) return "对方尚未绑定句柄。";
|
|
3202
3480
|
const initiatorHandle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -3448,7 +3726,9 @@ ${achievementList.join("\n")}`;
|
|
|
3448
3726
|
day: "2-digit"
|
|
3449
3727
|
})}`;
|
|
3450
3728
|
});
|
|
3451
|
-
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async (
|
|
3729
|
+
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async ({ session }, type) => {
|
|
3730
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3731
|
+
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
3452
3732
|
const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
|
|
3453
3733
|
stats[weapon.type] = (stats[weapon.type] || 0) + 1;
|
|
3454
3734
|
return stats;
|
|
@@ -3467,7 +3747,7 @@ ${achievementList.join("\n")}`;
|
|
|
3467
3747
|
return `无效武器类型,可用类型:
|
|
3468
3748
|
${validTypes.join("、")}`;
|
|
3469
3749
|
}
|
|
3470
|
-
const items = Object.entries(weaponConfig).filter(([
|
|
3750
|
+
const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
|
|
3471
3751
|
const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
|
|
3472
3752
|
return [
|
|
3473
3753
|
`【${name2}】`,
|
|
@@ -3476,57 +3756,126 @@ ${validTypes.join("、")}`;
|
|
|
3476
3756
|
`价格:${config2.price}金币`,
|
|
3477
3757
|
"特性:",
|
|
3478
3758
|
tagEffectsDesc,
|
|
3479
|
-
config2.description
|
|
3759
|
+
`描述:${config2.description}`
|
|
3480
3760
|
].join("\n");
|
|
3481
3761
|
});
|
|
3482
3762
|
return [
|
|
3483
3763
|
`🏪 咕咕武器库 - ${type} 🏪`,
|
|
3484
|
-
"
|
|
3764
|
+
"使用“购买 武器名称”命令进行购买",
|
|
3485
3765
|
"====================",
|
|
3486
3766
|
...items,
|
|
3487
3767
|
items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
|
|
3488
3768
|
].join("\n\n");
|
|
3489
3769
|
});
|
|
3490
|
-
ctx.command("ggcevo
|
|
3770
|
+
ctx.command("ggcevo/爆破库 [type]").usage("输入“爆破库”查看分类,或“爆破库 类型”查看详细物品").action(async ({ session }, type) => {
|
|
3771
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3772
|
+
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
3773
|
+
const filteredItems = Object.values(SyndicatedItems).filter(
|
|
3774
|
+
(item) => item.price > 0 && ["爆破物", "手榴弹"].includes(item.type)
|
|
3775
|
+
);
|
|
3776
|
+
const typeStats = filteredItems.reduce((stats, item) => {
|
|
3777
|
+
stats[item.type] = (stats[item.type] || 0) + 1;
|
|
3778
|
+
return stats;
|
|
3779
|
+
}, {});
|
|
3780
|
+
if (!type) {
|
|
3781
|
+
return [
|
|
3782
|
+
"💣 爆破装备库分类 💣",
|
|
3783
|
+
'使用 "爆破库 类型名称" 查看详细列表',
|
|
3784
|
+
"====================",
|
|
3785
|
+
...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
|
|
3786
|
+
"===================="
|
|
3787
|
+
].join("\n");
|
|
3788
|
+
}
|
|
3789
|
+
const validTypes = Object.keys(typeStats);
|
|
3790
|
+
if (!validTypes.includes(type)) {
|
|
3791
|
+
return `无效分类,可用类型:
|
|
3792
|
+
${validTypes.join("、")}`;
|
|
3793
|
+
}
|
|
3794
|
+
const items = filteredItems.filter((item) => item.type === type).map((item) => [
|
|
3795
|
+
`${Object.keys(SyndicatedItems).find((k) => SyndicatedItems[k] === item)}`,
|
|
3796
|
+
// 获取物品名称
|
|
3797
|
+
`类型:${item.type}`,
|
|
3798
|
+
`价格:${item.price}金币`,
|
|
3799
|
+
`效果:${item.effects}`,
|
|
3800
|
+
`描述:${item.description}`
|
|
3801
|
+
].join("\n"));
|
|
3802
|
+
return [
|
|
3803
|
+
`💣 爆破装备库 - ${type} 💣`,
|
|
3804
|
+
"使用“购买 物品名称”命令进行购买",
|
|
3805
|
+
"====================",
|
|
3806
|
+
...items,
|
|
3807
|
+
items.length === 0 ? "⚠️ 该分类下暂无可用物品" : ""
|
|
3808
|
+
].join("\n\n");
|
|
3809
|
+
});
|
|
3810
|
+
ctx.command("ggcevo/购买 <item>").action(async ({ session }, item) => {
|
|
3491
3811
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3492
3812
|
if (!profile) return "您暂未绑定句柄。";
|
|
3493
3813
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3494
3814
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3495
|
-
if (existingEntries.length > 0)
|
|
3496
|
-
|
|
3815
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
3816
|
+
const allItems = { ...weaponConfig, ...SyndicatedItems };
|
|
3817
|
+
if (!item) return "请输入“购买 物品名称”来购买所需物品。";
|
|
3818
|
+
const config2 = allItems[item];
|
|
3819
|
+
if (!config2) return "无效的物品名称,请重新输入。";
|
|
3820
|
+
if (config2.price <= 0) return "❌ 该物品不可直接购买";
|
|
3821
|
+
const isWeapon = ["能量武器", "热能武器", "实弹武器"].includes(config2.type);
|
|
3822
|
+
if (isWeapon) {
|
|
3823
|
+
const existingWeapon = await ctx.database.get("ggcevo_equipment", {
|
|
3824
|
+
handle,
|
|
3825
|
+
weaponId: config2.id
|
|
3826
|
+
});
|
|
3827
|
+
if (existingWeapon.length > 0) return `❌ 您已经拥有${item},无法重复购买`;
|
|
3497
3828
|
}
|
|
3498
3829
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
if (
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3830
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
3831
|
+
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 });
|
|
3832
|
+
let discountDetails = [];
|
|
3833
|
+
let totalDiscount = 0;
|
|
3834
|
+
if (isWeapon) {
|
|
3835
|
+
const techDiscountTable = {
|
|
3836
|
+
2: [0, 10],
|
|
3837
|
+
3: [0, 15],
|
|
3838
|
+
4: [0, 20],
|
|
3839
|
+
5: [0, 25]
|
|
3840
|
+
};
|
|
3841
|
+
const techLevel = weaponTech?.level || 0;
|
|
3842
|
+
if (techLevel >= 2) {
|
|
3843
|
+
const [baseDisc, careerDisc] = techDiscountTable[Math.min(techLevel, 5)] || [0, 0];
|
|
3844
|
+
const isQualifiedCareer = careerData?.career && Spacestationtechnology.find((t) => t.techId === 2)?.careerNames.includes(careerData.career);
|
|
3845
|
+
const techDiscount = isQualifiedCareer ? Math.max(baseDisc, careerDisc) : baseDisc;
|
|
3846
|
+
if (techDiscount > 0) {
|
|
3847
|
+
totalDiscount += techDiscount;
|
|
3848
|
+
discountDetails.push(
|
|
3849
|
+
`武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""} ${techDiscount}%折扣`
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3512
3853
|
}
|
|
3513
|
-
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
3854
|
+
const activeWish = isWeapon ? await ctx.database.get("ggcevo_Wish_Record", {
|
|
3514
3855
|
handle,
|
|
3515
3856
|
wishname: "蚱蜢优购",
|
|
3516
3857
|
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
3517
3858
|
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
3518
3859
|
isused: false
|
|
3519
|
-
}).then((records) => records[0]);
|
|
3520
|
-
let actualPrice = config2.price;
|
|
3521
|
-
let discountMessage = "";
|
|
3522
|
-
let equippedCount;
|
|
3860
|
+
}).then((records) => records[0]) : null;
|
|
3523
3861
|
if (activeWish) {
|
|
3524
|
-
|
|
3525
|
-
|
|
3862
|
+
const wishDiscount = 20;
|
|
3863
|
+
totalDiscount = 100 - (100 - totalDiscount) * (100 - wishDiscount) / 100;
|
|
3864
|
+
discountDetails.push(`蚱蜢优购祈愿生效 ${wishDiscount}%折扣`);
|
|
3865
|
+
}
|
|
3866
|
+
let actualPrice = config2.price;
|
|
3867
|
+
if (totalDiscount > 0) {
|
|
3868
|
+
actualPrice = Math.floor(config2.price * (100 - totalDiscount) / 100);
|
|
3869
|
+
actualPrice = Math.max(actualPrice, 1);
|
|
3526
3870
|
}
|
|
3527
3871
|
if ((signInfo?.totalRewards || 0) < actualPrice) {
|
|
3528
|
-
|
|
3872
|
+
let priceInfo = `需要 ${actualPrice} 金币`;
|
|
3873
|
+
if (discountDetails.length > 0) {
|
|
3874
|
+
priceInfo += `(原价 ${config2.price},累计折扣 ${totalDiscount}%)`;
|
|
3875
|
+
}
|
|
3876
|
+
return `❌ 金币不足,${priceInfo}`;
|
|
3529
3877
|
}
|
|
3878
|
+
let isAutoEquipped = false;
|
|
3530
3879
|
await ctx.database.withTransaction(async () => {
|
|
3531
3880
|
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
3532
3881
|
totalRewards: signInfo.totalRewards - actualPrice
|
|
@@ -3536,32 +3885,55 @@ ${validTypes.join("、")}`;
|
|
|
3536
3885
|
isused: true
|
|
3537
3886
|
});
|
|
3538
3887
|
}
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3888
|
+
if (isWeapon) {
|
|
3889
|
+
await ctx.database.upsert("ggcevo_equipment", [{
|
|
3890
|
+
handle,
|
|
3891
|
+
weaponId: config2.id,
|
|
3892
|
+
level: 0,
|
|
3893
|
+
modificationSlots: 1,
|
|
3894
|
+
equipped: false
|
|
3895
|
+
}], ["handle", "weaponId"]);
|
|
3896
|
+
const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
|
|
3897
|
+
if (equippedCount === 0) {
|
|
3898
|
+
await ctx.database.set(
|
|
3899
|
+
"ggcevo_equipment",
|
|
3900
|
+
{ handle, weaponId: config2.id },
|
|
3901
|
+
{ equipped: true }
|
|
3902
|
+
);
|
|
3903
|
+
isAutoEquipped = true;
|
|
3904
|
+
}
|
|
3905
|
+
} else {
|
|
3906
|
+
const [existing] = await ctx.database.get("ggcevo_warehouse", {
|
|
3907
|
+
handle,
|
|
3908
|
+
itemId: config2.id
|
|
3909
|
+
});
|
|
3910
|
+
await ctx.database.upsert("ggcevo_warehouse", [{
|
|
3911
|
+
handle,
|
|
3912
|
+
itemId: config2.id,
|
|
3913
|
+
quantity: (existing?.quantity || 0) + 1
|
|
3914
|
+
}], ["handle", "itemId"]);
|
|
3553
3915
|
}
|
|
3554
3916
|
});
|
|
3555
|
-
let message =
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3917
|
+
let message = `✅ 成功获取 ${isWeapon ? "武器" : "物品"}「${item}」
|
|
3918
|
+
`;
|
|
3919
|
+
message += `花费 ${actualPrice} 金币`;
|
|
3920
|
+
if (discountDetails.length > 0) {
|
|
3921
|
+
message += `(原价 ${config2.price} 金币)
|
|
3922
|
+
折扣明细:
|
|
3923
|
+
▸ ${discountDetails.join("\n▸ ")}`;
|
|
3559
3924
|
}
|
|
3560
|
-
if (
|
|
3925
|
+
if (isWeapon) {
|
|
3926
|
+
if (isAutoEquipped) {
|
|
3927
|
+
message += "\n\n【系统已自动装备该武器】";
|
|
3928
|
+
}
|
|
3929
|
+
message += "\n输入「武器仓库」查看详情";
|
|
3930
|
+
} else {
|
|
3931
|
+
const [current] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: config2.id });
|
|
3561
3932
|
message += `
|
|
3562
|
-
|
|
3933
|
+
|
|
3934
|
+
当前持有数量:${current?.quantity || 1},输入「仓库」查看物品`;
|
|
3563
3935
|
}
|
|
3564
|
-
return message
|
|
3936
|
+
return message;
|
|
3565
3937
|
});
|
|
3566
3938
|
ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
|
|
3567
3939
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
@@ -3586,7 +3958,7 @@ ${validTypes.join("、")}`;
|
|
|
3586
3958
|
}));
|
|
3587
3959
|
return [
|
|
3588
3960
|
"🛡️ 您当前拥有的武器",
|
|
3589
|
-
'使用"
|
|
3961
|
+
'使用"装备 武器名称"来装备武器',
|
|
3590
3962
|
"⚡表示当前装备武器",
|
|
3591
3963
|
"──────────────",
|
|
3592
3964
|
...weaponDetails.length ? weaponDetails : ["空空如也,快去“武器库”看看吧!"],
|
|
@@ -3595,11 +3967,11 @@ ${validTypes.join("、")}`;
|
|
|
3595
3967
|
"🔧 改装效果在战斗中生效"
|
|
3596
3968
|
].join("\n");
|
|
3597
3969
|
});
|
|
3598
|
-
ctx.command("ggcevo
|
|
3970
|
+
ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
|
|
3599
3971
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3600
3972
|
if (!profile) return "您暂未绑定句柄。";
|
|
3601
|
-
if (!weapon) return "
|
|
3602
|
-
if (!weaponConfig[weapon]) return "
|
|
3973
|
+
if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
3974
|
+
if (!weaponConfig[weapon]) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
3603
3975
|
const config2 = weaponConfig[weapon];
|
|
3604
3976
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3605
3977
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -3629,67 +4001,26 @@ ${validTypes.join("、")}`;
|
|
|
3629
4001
|
});
|
|
3630
4002
|
return `您已成功装备武器 ${weapon}!`;
|
|
3631
4003
|
});
|
|
3632
|
-
ctx.command("ggcevo
|
|
4004
|
+
ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
|
|
3633
4005
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3634
|
-
if (!profile) return "
|
|
4006
|
+
if (!profile) return "❌ 您暂未绑定句柄";
|
|
3635
4007
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
3639
|
-
}
|
|
3640
|
-
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
3641
|
-
const [equipment] = await ctx.database.get("ggcevo_equipment", {
|
|
3642
|
-
handle,
|
|
3643
|
-
weaponId: weaponConfig[weapon]?.id
|
|
3644
|
-
});
|
|
3645
|
-
if (!weapon) return "请输入“升级武器 武器名称”来升级你想要的武器。";
|
|
3646
|
-
if (!equipment) return "尚未获得该武器。";
|
|
3647
|
-
if (equipment.level >= 6) return "该武器已达最大升级等级。";
|
|
3648
|
-
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
3649
|
-
handle,
|
|
3650
|
-
wishname: "灵狐升运",
|
|
3651
|
-
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
3652
|
-
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
3653
|
-
isused: false
|
|
3654
|
-
}).then((records) => records[0]);
|
|
3655
|
-
let baseCost = [1050, 1450, 1850, 2250, 2650, 3050][equipment.level];
|
|
3656
|
-
let actualCost = baseCost;
|
|
3657
|
-
let discountMessage = "";
|
|
3658
|
-
if (activeWish) {
|
|
3659
|
-
actualCost = Math.floor(baseCost * 0.8);
|
|
3660
|
-
discountMessage = ` (祈愿优惠价,原价${baseCost})`;
|
|
4008
|
+
if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
|
|
4009
|
+
return "❌ 拒绝访问,您已被列入黑名单";
|
|
3661
4010
|
}
|
|
3662
|
-
if (
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
}, {
|
|
3672
|
-
level: equipment.level + 1,
|
|
3673
|
-
modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
|
|
3674
|
-
});
|
|
3675
|
-
if (activeWish) {
|
|
3676
|
-
await ctx.database.set("ggcevo_Wish_Record", { id: activeWish.id }, {
|
|
3677
|
-
isused: true
|
|
3678
|
-
});
|
|
3679
|
-
}
|
|
3680
|
-
});
|
|
3681
|
-
const newLevel = equipment.level + 1;
|
|
3682
|
-
const baseDamage = (weaponConfig[weapon].damage * (1 + 0.1 * newLevel)).toFixed(1);
|
|
3683
|
-
const slots = Math.floor(newLevel / 3) + 1;
|
|
3684
|
-
let message = `${weapon} 升级成功!花费${actualCost}枚金币${discountMessage}。`;
|
|
3685
|
-
if (activeWish) {
|
|
3686
|
-
message += `
|
|
3687
|
-
🦊 灵狐升运祈愿已使用,下次升级将恢复原价。`;
|
|
4011
|
+
if (!target) return "⚠️ 请输入要升级的武器或科技名称(升级科技需要加入人类联盟阵营)";
|
|
4012
|
+
const isTech = Spacestationtechnology.some(
|
|
4013
|
+
(t) => t.techname === target || t.techname == target
|
|
4014
|
+
);
|
|
4015
|
+
const isWeapon = Object.keys(weaponConfig).includes(target);
|
|
4016
|
+
if (isTech) {
|
|
4017
|
+
return handleTechUpgrade(handle, target);
|
|
4018
|
+
} else if (isWeapon) {
|
|
4019
|
+
return handleWeaponUpgrade(handle, target);
|
|
3688
4020
|
}
|
|
3689
|
-
return
|
|
3690
|
-
当前等级:${newLevel},伤害:${baseDamage},拥有改装槽:${slots}个。`;
|
|
4021
|
+
return `❌ 未找到 "${target}" 对应的武器或科技`;
|
|
3691
4022
|
});
|
|
3692
|
-
ctx.command("ggcevo
|
|
4023
|
+
ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
|
|
3693
4024
|
const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
|
|
3694
4025
|
const generateModList = /* @__PURE__ */ __name(() => {
|
|
3695
4026
|
if (!isValidWeapon) {
|
|
@@ -3707,7 +4038,7 @@ ${validTypes.join("、")}`;
|
|
|
3707
4038
|
if (!mod || !modConfig[mod]) {
|
|
3708
4039
|
return [
|
|
3709
4040
|
isValidWeapon ? `🛠️ ${weapon} 专属模块 🛠️` : "🛠️ 通用武器模块 🛠️",
|
|
3710
|
-
isValidWeapon ?
|
|
4041
|
+
isValidWeapon ? `使用「改装 ${weapon} 模块名称」安装专属模块` : weapon ? "※ 无效武器名称,请使用「改装 武器名称 模块名称」安装模块" : "※ 输入「改装 武器名称」查询专属模块\n※ 安装模块:「改装 武器名称 模块名称」",
|
|
3711
4042
|
"====================",
|
|
3712
4043
|
generateModList()
|
|
3713
4044
|
].join("\n\n");
|
|
@@ -3782,7 +4113,7 @@ ${validTypes.join("、")}`;
|
|
|
3782
4113
|
if (!targetBoss) {
|
|
3783
4114
|
const activeNames = await getActiveBossNames();
|
|
3784
4115
|
return `当前没有找到名为 ${bossName} 的可攻击目标。
|
|
3785
|
-
|
|
4116
|
+
请攻击当前存活的异形:${activeNames || "无"}。`;
|
|
3786
4117
|
}
|
|
3787
4118
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3788
4119
|
if (!profile) return "您暂未绑定句柄。";
|
|
@@ -3805,7 +4136,7 @@ ${validTypes.join("、")}`;
|
|
|
3805
4136
|
handle,
|
|
3806
4137
|
equipped: true
|
|
3807
4138
|
});
|
|
3808
|
-
if (!equippedWeapon) return "
|
|
4139
|
+
if (!equippedWeapon) return "请先输入“装备 武器名称”后再攻击。";
|
|
3809
4140
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
3810
4141
|
const [weaponName, weaponData] = weaponConfigEntry;
|
|
3811
4142
|
const { damage: baseDamage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
@@ -3955,7 +4286,8 @@ ${validTypes.join("、")}`;
|
|
|
3955
4286
|
const resultMessage = [
|
|
3956
4287
|
`🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
|
|
3957
4288
|
...effectMessage.length > 0 ? [
|
|
3958
|
-
|
|
4289
|
+
`触发效果:
|
|
4290
|
+
${effectMessage.join("\n")}`
|
|
3959
4291
|
] : [],
|
|
3960
4292
|
`造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
|
|
3961
4293
|
...healMessages,
|
|
@@ -3971,6 +4303,57 @@ ${validTypes.join("、")}`;
|
|
|
3971
4303
|
await ctx.broadcast(groupId, finalBroadcast);
|
|
3972
4304
|
}
|
|
3973
4305
|
});
|
|
4306
|
+
ctx.command("ggcevo/攻击假人").usage("测试当前装备武器的伤害,可添加标签和被动\n用法:攻击假人 [--标签 标签1 标签2] [--被动 被动1 被动2]").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").option("passives", "-p <passives:string> 添加BOSS被动(逗号分隔)").action(async (argv) => {
|
|
4307
|
+
const session = argv.session;
|
|
4308
|
+
const { options } = argv;
|
|
4309
|
+
const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
|
|
4310
|
+
const tags = parseList(options.tags);
|
|
4311
|
+
const passives = parseList(options.passives);
|
|
4312
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4313
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
4314
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4315
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4316
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
4317
|
+
const [equippedWeapon] = await ctx.database.get("ggcevo_equipment", {
|
|
4318
|
+
handle,
|
|
4319
|
+
equipped: true
|
|
4320
|
+
});
|
|
4321
|
+
if (!equippedWeapon) return '请先输入"装备 武器名称"后再测试。';
|
|
4322
|
+
const dummyBoss = {
|
|
4323
|
+
name: "测试假人",
|
|
4324
|
+
HP: Infinity,
|
|
4325
|
+
type: "主宰",
|
|
4326
|
+
groupId: 0,
|
|
4327
|
+
skills: passives || [],
|
|
4328
|
+
// 从选项获取被动
|
|
4329
|
+
tags: tags || []
|
|
4330
|
+
// 从选项获取标签
|
|
4331
|
+
};
|
|
4332
|
+
const { damage, hasCrit, effectMessage } = await calculateTotalDamage(
|
|
4333
|
+
ctx,
|
|
4334
|
+
session,
|
|
4335
|
+
equippedWeapon,
|
|
4336
|
+
dummyBoss,
|
|
4337
|
+
{
|
|
4338
|
+
isTest: true,
|
|
4339
|
+
// 标记为测试模式
|
|
4340
|
+
customTags: tags,
|
|
4341
|
+
customPassives: passives
|
|
4342
|
+
}
|
|
4343
|
+
);
|
|
4344
|
+
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
4345
|
+
const [weaponName] = weaponConfigEntry;
|
|
4346
|
+
return [
|
|
4347
|
+
`🎯 测试攻击 ${dummyBoss.name}`,
|
|
4348
|
+
`💥 使用武器:${weaponName}`,
|
|
4349
|
+
options.tags?.length && `🏷️ 模拟标签:${tags.join(", ")}`,
|
|
4350
|
+
options.passives?.length && `🛡️ 模拟被动:${passives.join(", ")}`,
|
|
4351
|
+
`📊 理论伤害值:${damage}`,
|
|
4352
|
+
hasCrit ? "✨ 触发暴击" : "",
|
|
4353
|
+
...effectMessage,
|
|
4354
|
+
"⚠️ 注意:假人默认无属性,标签和被动需手动添加"
|
|
4355
|
+
].filter((line) => line).join("\n");
|
|
4356
|
+
});
|
|
3974
4357
|
ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
3975
4358
|
const pageNum = parseInt(page) || 1;
|
|
3976
4359
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
@@ -4056,7 +4439,7 @@ ${validTypes.join("、")}`;
|
|
|
4056
4439
|
name: minion.name,
|
|
4057
4440
|
type: "子代",
|
|
4058
4441
|
HP: minion.maxHP,
|
|
4059
|
-
tags:
|
|
4442
|
+
tags: minion.tags,
|
|
4060
4443
|
skills: [...minion.passive],
|
|
4061
4444
|
groupId: groupid,
|
|
4062
4445
|
isActive: true,
|
|
@@ -4301,13 +4684,11 @@ ${validTypes.join("、")}`;
|
|
|
4301
4684
|
}
|
|
4302
4685
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4303
4686
|
if (!careerData) return "请先加入阵营后使用转职功能。";
|
|
4304
|
-
let config2
|
|
4687
|
+
let config2;
|
|
4305
4688
|
if (careerData.group === "人类联盟") {
|
|
4306
4689
|
config2 = spaceStationCrewConfig;
|
|
4307
|
-
factionTips = "💰 转职消耗金币";
|
|
4308
4690
|
} else if (careerData.group === "辛迪加海盗") {
|
|
4309
4691
|
config2 = syndicatePirateConfig;
|
|
4310
|
-
factionTips = "💰 消耗金币 + 🔴 消耗红晶";
|
|
4311
4692
|
} else {
|
|
4312
4693
|
return "未知阵营无法显示职业信息。";
|
|
4313
4694
|
}
|
|
@@ -4396,7 +4777,6 @@ ${validTypes.join("、")}`;
|
|
|
4396
4777
|
`🗓️ 就职时间:${formattedDate}`
|
|
4397
4778
|
];
|
|
4398
4779
|
if (careerData.group === "辛迪加海盗") {
|
|
4399
|
-
infoCard.push(`🔴 持有红晶:${careerData.redcrystal || 0} 个`);
|
|
4400
4780
|
infoCard.push("💡 提示:红晶可通过主动PK获得(无论胜负)");
|
|
4401
4781
|
} else {
|
|
4402
4782
|
infoCard.push("💡 提示:使用「转职」命令可变更职业");
|
|
@@ -4419,10 +4799,13 @@ ${validTypes.join("、")}`;
|
|
|
4419
4799
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
4420
4800
|
return "🚫 该功能需要【辛迪加海盗】阵营权限";
|
|
4421
4801
|
}
|
|
4422
|
-
const typeStats =
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
}
|
|
4802
|
+
const typeStats = {};
|
|
4803
|
+
Object.values(weaponConfig).filter((config2) => config2.redCrystalCost > 0).forEach((weapon) => {
|
|
4804
|
+
typeStats[weapon.type] = (typeStats[weapon.type] || 0) + 1;
|
|
4805
|
+
});
|
|
4806
|
+
Object.values(SyndicatedItems).filter((item) => item.redCrystalCost > 0).forEach((item) => {
|
|
4807
|
+
typeStats[item.type] = (typeStats[item.type] || 0) + 1;
|
|
4808
|
+
});
|
|
4426
4809
|
if (!type) {
|
|
4427
4810
|
return [
|
|
4428
4811
|
"🏴☠️ 辛迪加黑市 🏴☠️",
|
|
@@ -4434,30 +4817,45 @@ ${validTypes.join("、")}`;
|
|
|
4434
4817
|
}
|
|
4435
4818
|
const normalizedType = Object.keys(typeStats).find((t) => t === type);
|
|
4436
4819
|
if (!normalizedType) return `无效类型,可用:${Object.keys(typeStats).join("、")}`;
|
|
4437
|
-
const items =
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4820
|
+
const items = [
|
|
4821
|
+
...Object.entries(weaponConfig).filter(
|
|
4822
|
+
([_, config2]) => config2.type === normalizedType && config2.redCrystalCost > 0
|
|
4823
|
+
).map(([name2, config2]) => {
|
|
4824
|
+
const infoBlocks = [
|
|
4825
|
+
`【${name2}】`,
|
|
4826
|
+
`类型:${config2.type}`,
|
|
4827
|
+
...config2.damage ? [`基础伤害:${config2.damage}`] : [],
|
|
4828
|
+
`订购价:${config2.redCrystalCost}红晶`
|
|
4829
|
+
// 只显示红晶价格
|
|
4830
|
+
];
|
|
4831
|
+
if (Object.keys(config2.tagEffects).length > 0) {
|
|
4832
|
+
const tagEffectsDesc = Object.entries(config2.tagEffects).map(([tag, mul]) => `▸ 对${tag}目标造成${(mul * 100).toFixed(0)}%伤害`).join("\n");
|
|
4833
|
+
infoBlocks.push("特性:", tagEffectsDesc);
|
|
4834
|
+
}
|
|
4835
|
+
infoBlocks.push(
|
|
4836
|
+
`描述:${config2.description}`,
|
|
4837
|
+
"──────────────"
|
|
4838
|
+
);
|
|
4839
|
+
return infoBlocks.join("\n");
|
|
4840
|
+
}),
|
|
4841
|
+
...Object.entries(SyndicatedItems).filter(
|
|
4842
|
+
([_, item]) => item.type === normalizedType && item.redCrystalCost > 0
|
|
4843
|
+
).map(([name2, item]) => {
|
|
4844
|
+
const infoBlocks = [
|
|
4845
|
+
`【${name2}】`,
|
|
4846
|
+
`类型:${item.type}`,
|
|
4847
|
+
`订购价:${item.redCrystalCost}红晶`,
|
|
4848
|
+
// 只显示红晶价格
|
|
4849
|
+
`效果:${item.effects}`,
|
|
4850
|
+
`描述:${item.description}`,
|
|
4851
|
+
"──────────────"
|
|
4852
|
+
];
|
|
4853
|
+
return infoBlocks.join("\n");
|
|
4854
|
+
})
|
|
4855
|
+
];
|
|
4458
4856
|
return [
|
|
4459
4857
|
`🏴☠️ 辛迪加黑市 - ${normalizedType} 🏴☠️`,
|
|
4460
|
-
"使用“订购
|
|
4858
|
+
"使用“订购 物品名称”进行购买(仅消耗红晶)",
|
|
4461
4859
|
"====================",
|
|
4462
4860
|
...items
|
|
4463
4861
|
].join("\n\n");
|
|
@@ -4466,27 +4864,27 @@ ${validTypes.join("、")}`;
|
|
|
4466
4864
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4467
4865
|
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
4468
4866
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4469
|
-
|
|
4470
|
-
if (existingEntries.length > 0) {
|
|
4867
|
+
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
4471
4868
|
return "❌ 拒绝访问,您已被列入黑名单";
|
|
4472
4869
|
}
|
|
4473
4870
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4474
4871
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
4475
4872
|
return "🚫 该功能需要【辛迪加海盗】阵营权限";
|
|
4476
4873
|
}
|
|
4477
|
-
if (!item) return "
|
|
4478
|
-
const
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
const
|
|
4874
|
+
if (!item) return "请输入“订购 物品名称”来向辛迪加订购物品。";
|
|
4875
|
+
const isWeapon = Object.prototype.hasOwnProperty.call(weaponConfig, item);
|
|
4876
|
+
const isSyndicatedItem = Object.prototype.hasOwnProperty.call(SyndicatedItems, item);
|
|
4877
|
+
if (!isWeapon && !isSyndicatedItem) return "❌ 无效物品名称";
|
|
4878
|
+
const itemConfig2 = isWeapon ? weaponConfig[item] : SyndicatedItems[item];
|
|
4879
|
+
if (!itemConfig2.redCrystalCost) return "⛔ 该物品不可订购";
|
|
4482
4880
|
if (isWeapon) {
|
|
4483
4881
|
const existing = await ctx.database.get("ggcevo_equipment", {
|
|
4484
4882
|
handle,
|
|
4485
|
-
weaponId:
|
|
4883
|
+
weaponId: itemConfig2.id
|
|
4486
4884
|
});
|
|
4487
|
-
if (existing.length) return "
|
|
4885
|
+
if (existing.length) return "您已经拥有该武器。";
|
|
4488
4886
|
}
|
|
4489
|
-
const requiredRed =
|
|
4887
|
+
const requiredRed = itemConfig2.redCrystalCost;
|
|
4490
4888
|
if ((careerData.redcrystal || 0) < requiredRed) {
|
|
4491
4889
|
return `❌ 红晶不足!需要:${requiredRed} 当前:${careerData.redcrystal}`;
|
|
4492
4890
|
}
|
|
@@ -4495,48 +4893,56 @@ ${validTypes.join("、")}`;
|
|
|
4495
4893
|
redcrystal: careerData.redcrystal - requiredRed
|
|
4496
4894
|
});
|
|
4497
4895
|
if (isWeapon) {
|
|
4498
|
-
await ctx.database.
|
|
4896
|
+
await ctx.database.create("ggcevo_equipment", {
|
|
4499
4897
|
handle,
|
|
4500
|
-
weaponId:
|
|
4898
|
+
weaponId: itemConfig2.id,
|
|
4501
4899
|
level: 0,
|
|
4502
4900
|
modificationSlots: 1,
|
|
4901
|
+
installedMods: [],
|
|
4503
4902
|
equipped: false
|
|
4504
|
-
}
|
|
4903
|
+
});
|
|
4505
4904
|
const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
|
|
4506
4905
|
if (equippedCount === 0) {
|
|
4507
4906
|
await ctx.database.set(
|
|
4508
4907
|
"ggcevo_equipment",
|
|
4509
|
-
{ handle, weaponId:
|
|
4908
|
+
{ handle, weaponId: itemConfig2.id },
|
|
4510
4909
|
{ equipped: true }
|
|
4511
4910
|
);
|
|
4512
4911
|
}
|
|
4513
4912
|
} else {
|
|
4514
|
-
const
|
|
4913
|
+
const [existing] = await ctx.database.get("ggcevo_warehouse", {
|
|
4515
4914
|
handle,
|
|
4516
|
-
itemId:
|
|
4915
|
+
itemId: itemConfig2.id
|
|
4517
4916
|
});
|
|
4518
4917
|
await ctx.database.upsert("ggcevo_warehouse", [{
|
|
4519
4918
|
handle,
|
|
4520
|
-
itemId:
|
|
4521
|
-
quantity: (
|
|
4919
|
+
itemId: itemConfig2.id,
|
|
4920
|
+
quantity: (existing?.quantity || 0) + 1
|
|
4522
4921
|
}], ["handle", "itemId"]);
|
|
4523
4922
|
}
|
|
4524
4923
|
});
|
|
4525
4924
|
if (isWeapon) {
|
|
4526
|
-
const
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4925
|
+
const equippedStatus = await ctx.database.get("ggcevo_equipment", {
|
|
4926
|
+
handle,
|
|
4927
|
+
weaponId: itemConfig2.id
|
|
4928
|
+
}).then((r) => r[0]?.equipped ? "已自动装备武器" : "需手动装备武器");
|
|
4929
|
+
return [
|
|
4930
|
+
`✅ 成功订购【${item}】!`,
|
|
4931
|
+
`消耗红晶:${requiredRed}`,
|
|
4932
|
+
`装备状态:${equippedStatus}`,
|
|
4933
|
+
'输入 "武器仓库" 管理武器'
|
|
4934
|
+
].join("\n");
|
|
4532
4935
|
} else {
|
|
4533
|
-
const
|
|
4936
|
+
const currentStock = await ctx.database.get("ggcevo_warehouse", {
|
|
4534
4937
|
handle,
|
|
4535
|
-
itemId:
|
|
4536
|
-
});
|
|
4537
|
-
return
|
|
4538
|
-
|
|
4539
|
-
|
|
4938
|
+
itemId: itemConfig2.id
|
|
4939
|
+
}).then((r) => r[0]?.quantity || 1);
|
|
4940
|
+
return [
|
|
4941
|
+
`✅ 成功订购【${item}】x1!`,
|
|
4942
|
+
`消耗红晶:${requiredRed}`,
|
|
4943
|
+
`当前库存:${currentStock}件`,
|
|
4944
|
+
'输入 "仓库" 查看所有物品'
|
|
4945
|
+
].join("\n");
|
|
4540
4946
|
}
|
|
4541
4947
|
});
|
|
4542
4948
|
ctx.command("ggcevo/仓库").action(async (argv) => {
|
|
@@ -4554,63 +4960,146 @@ ${validTypes.join("、")}`;
|
|
|
4554
4960
|
const message = [`【${handle}的仓库】`];
|
|
4555
4961
|
message.push(`💰 金币:${totalRewards}`);
|
|
4556
4962
|
if (redcrystal > 0) message.push(`🔴 红晶:${redcrystal}`);
|
|
4557
|
-
const validItems = items.filter(
|
|
4963
|
+
const validItems = items.filter(
|
|
4964
|
+
(item) => Object.values(SyndicatedItems).some(
|
|
4965
|
+
(specialItem) => specialItem.id === item.itemId
|
|
4966
|
+
) && item.quantity > 0
|
|
4967
|
+
);
|
|
4558
4968
|
if (!validItems.length) {
|
|
4559
|
-
message.push("
|
|
4969
|
+
message.push("你的特殊物品仓库空空如也。");
|
|
4560
4970
|
} else {
|
|
4561
4971
|
message.push(
|
|
4562
4972
|
validItems.map((warehouseItem) => {
|
|
4563
|
-
const entry = Object.entries(
|
|
4973
|
+
const entry = Object.entries(SyndicatedItems).find(
|
|
4564
4974
|
([, item]) => item.id === warehouseItem.itemId
|
|
4565
4975
|
);
|
|
4566
|
-
if (!entry) return `未知物品 x ${warehouseItem.quantity}:数据异常,请联系管理员`;
|
|
4567
4976
|
const [itemName, itemData] = entry;
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4977
|
+
return [
|
|
4978
|
+
`${itemName}`,
|
|
4979
|
+
// 移除数量显示在标题
|
|
4980
|
+
`类型:${itemData.type} | 持有数量:${warehouseItem.quantity}`,
|
|
4981
|
+
// 从warehouse表读取实际数量
|
|
4982
|
+
`特效:${itemData.effects}`,
|
|
4983
|
+
`描述:${itemData.description}`,
|
|
4984
|
+
"―――――――――――――――"
|
|
4985
|
+
].join("\n");
|
|
4572
4986
|
}).join("\n\n")
|
|
4573
4987
|
);
|
|
4574
4988
|
}
|
|
4575
4989
|
return message.join("\n");
|
|
4576
4990
|
});
|
|
4577
|
-
ctx.command("ggcevo/使用 [itemName]").action(async (argv, itemName) => {
|
|
4991
|
+
ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
|
|
4578
4992
|
const session = argv.session;
|
|
4579
4993
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4580
|
-
if (!profile) return "
|
|
4994
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4581
4995
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
return "❌ 拒绝访问,您已被列入黑名单";
|
|
4996
|
+
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
4997
|
+
return "⛔ 您已被列入黑名单";
|
|
4585
4998
|
}
|
|
4586
4999
|
try {
|
|
4587
|
-
const
|
|
4588
|
-
const targetItem =
|
|
4589
|
-
const entry = Object.entries(
|
|
4590
|
-
([,
|
|
5000
|
+
const warehouseItems = await ctx.database.get("ggcevo_warehouse", { handle });
|
|
5001
|
+
const targetItem = warehouseItems.find((item) => {
|
|
5002
|
+
const entry = Object.entries(SyndicatedItems).find(
|
|
5003
|
+
([_, cfg]) => cfg.id === item.itemId
|
|
4591
5004
|
);
|
|
4592
|
-
|
|
4593
|
-
const [itemKey] = entry;
|
|
4594
|
-
return itemKey.toLowerCase() === itemName?.toLowerCase();
|
|
5005
|
+
return entry?.[0] === itemName;
|
|
4595
5006
|
});
|
|
4596
|
-
if (!targetItem) return
|
|
4597
|
-
if (targetItem.quantity < 1) return
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
await
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
5007
|
+
if (!targetItem) return `❌ 未找到 ${itemName} 或物品不可用`;
|
|
5008
|
+
if (targetItem.quantity < 1) return `⚠️ ${itemName} 库存不足`;
|
|
5009
|
+
const itemEntry = Object.entries(SyndicatedItems).find(
|
|
5010
|
+
([_, item]) => item.id === targetItem.itemId
|
|
5011
|
+
);
|
|
5012
|
+
const [itemNameConfirmed, itemConfig2] = itemEntry;
|
|
5013
|
+
const effectResult = await applyItemEffect(session, handle, itemConfig2, target);
|
|
5014
|
+
if (!effectResult.success) return effectResult.message;
|
|
5015
|
+
const newQuantity = targetItem.quantity - 1;
|
|
5016
|
+
await ctx.database.set(
|
|
5017
|
+
"ggcevo_warehouse",
|
|
5018
|
+
{ handle, itemId: targetItem.itemId },
|
|
5019
|
+
{ quantity: newQuantity }
|
|
5020
|
+
);
|
|
5021
|
+
return [
|
|
5022
|
+
`✅ 成功使用 ${itemNameConfirmed}`,
|
|
5023
|
+
`├ 剩余数量:${newQuantity}`,
|
|
5024
|
+
`└ 效果触发:${effectResult.message}`,
|
|
5025
|
+
"─".repeat(25)
|
|
5026
|
+
].join("\n");
|
|
4609
5027
|
} catch (error) {
|
|
4610
5028
|
ctx.logger("GGCEVO").error(error);
|
|
4611
|
-
return "
|
|
5029
|
+
return "⚠️ 物品使用失败,请联系管理员";
|
|
4612
5030
|
}
|
|
4613
5031
|
});
|
|
5032
|
+
ctx.command("ggcevo/科技信息", "查看空间站科技配置").action(async ({ session }) => {
|
|
5033
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5034
|
+
if (!profile) return "❌ 您暂未绑定句柄。";
|
|
5035
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5036
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5037
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
5038
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
5039
|
+
}
|
|
5040
|
+
const techEntries = await ctx.database.get("ggcevo_tech", { handle });
|
|
5041
|
+
const techInfo = Spacestationtechnology.map((tech) => {
|
|
5042
|
+
const entry = techEntries.find((e) => e.techId === tech.techId);
|
|
5043
|
+
const currentLevel = entry?.level || 0;
|
|
5044
|
+
const levelData = tech.levels.find((l) => l.level === currentLevel);
|
|
5045
|
+
let description = "尚未解锁";
|
|
5046
|
+
let careerBonus = "无";
|
|
5047
|
+
if (levelData) {
|
|
5048
|
+
description = levelData.description;
|
|
5049
|
+
careerBonus = levelData.careerBonus;
|
|
5050
|
+
}
|
|
5051
|
+
return `🛠️ ${tech.techname} [${currentLevel}/${tech.maxLevel}]
|
|
5052
|
+
📌 效果:${description}
|
|
5053
|
+
🎖️ ${careerBonus}`;
|
|
5054
|
+
}).join("\n\n");
|
|
5055
|
+
return `🚀 空间站科技配置信息:
|
|
5056
|
+
|
|
5057
|
+
${techInfo}`;
|
|
5058
|
+
});
|
|
5059
|
+
ctx.command("ggcevo/科技 [techName]", "查看空间站科技信息").usage("输入“科技”查看列表,或“科技 科技名称”查看详细信息").action(async ({ session }, techName) => {
|
|
5060
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5061
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5062
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5063
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5064
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
5065
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
5066
|
+
}
|
|
5067
|
+
const romanNumerals = { 1: "I", 2: "II", 3: "III", 4: "IV", 5: "V" };
|
|
5068
|
+
if (!techName) {
|
|
5069
|
+
const techList = Spacestationtechnology.map(
|
|
5070
|
+
(tech2) => `▸ ${tech2.techname} (最大等级 ${romanNumerals[tech2.maxLevel]})`
|
|
5071
|
+
);
|
|
5072
|
+
return [
|
|
5073
|
+
"🛰️ 空间站科技系统 🛰️",
|
|
5074
|
+
'使用 "科技 科技名称" 查看详细信息',
|
|
5075
|
+
"====================",
|
|
5076
|
+
...techList,
|
|
5077
|
+
"===================="
|
|
5078
|
+
].join("\n");
|
|
5079
|
+
}
|
|
5080
|
+
const tech = Spacestationtechnology.find(
|
|
5081
|
+
(t) => t.techname === techName
|
|
5082
|
+
);
|
|
5083
|
+
if (!tech) return `❌ 无效科技名称,可用科技:
|
|
5084
|
+
${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
5085
|
+
const techDetails = tech.levels.map((level) => {
|
|
5086
|
+
return [
|
|
5087
|
+
`✦ 等级 ${romanNumerals[level.level]}`,
|
|
5088
|
+
`▸ 升级花费:${level.cost}金币`,
|
|
5089
|
+
`▸ 基础效果:${level.description}`,
|
|
5090
|
+
`💼 ${level.careerBonus}`,
|
|
5091
|
+
"------------------"
|
|
5092
|
+
].join("\n");
|
|
5093
|
+
});
|
|
5094
|
+
return [
|
|
5095
|
+
`🛠️ ${tech.techname} 科技详情 🛠️`,
|
|
5096
|
+
`最大可升级等级:${romanNumerals[tech.maxLevel]}`,
|
|
5097
|
+
'使用 "升级 科技名称" 进行升级',
|
|
5098
|
+
"====================",
|
|
5099
|
+
...techDetails,
|
|
5100
|
+
"===================="
|
|
5101
|
+
].join("\n");
|
|
5102
|
+
});
|
|
4614
5103
|
}
|
|
4615
5104
|
__name(apply, "apply");
|
|
4616
5105
|
function simpleDraw() {
|