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.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("黑名单通知群组").default([]),
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
- const SyndicatedItems = {
282
- "E-2能量炸弹": {
283
- id: 1e3,
284
- type: "爆破物",
285
- description: "一种小型的机械装置,用于吸收空间站能量并进行爆破",
286
- redCrystalCost: 30,
287
- effects: "当主宰为“空间站感染虫”时才能使用,对“空间站哨枪塔”造成其当前血量值的伤害(获得等同于伤害值的金币)",
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
- effects: ""
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
- ...SyndicatedItems
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: 12e3,
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: 4e3,
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: "升级联盟空间站科技享有80%的折扣",
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: "拥有一把武器等级为3级以上的能量武器",
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级,升级武器享有80%的折扣(可与祈愿叠加)",
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: "热能武器攻击伤害+15%",
785
- requirements: "",
786
- Jobtransfer: false,
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, bossName, equippedWeapon) {
876
- const bossRecord = await ctx.database.get("ggcevo_boss", { name: bossName });
877
- if (!bossRecord || !bossRecord.length) {
878
- throw new Error(`未找到BOSS记录: ${bossName}`);
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
- bossTags.forEach((tag) => {
883
- let effectValue;
884
- if (tag === "重甲" && equippedWeapon.installedMods.includes("裂甲核心")) {
885
- effectValue = 1.2;
886
- } else if (tag === "惧热" && equippedWeapon.installedMods.includes("助燃核心")) {
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(targetBoss) {
963
+ function calculatePassiveEffects(passives) {
897
964
  let passiveEffect = 0;
898
- const effectivePassives = [...targetBoss.skills || []];
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 targetBossConfig = targetBoss.name;
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(targetBoss);
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: `需要拥有一把等级6以上的能量武器`
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, itemId) {
1762
- const itemConfig2 = Object.values(weaponConfig).find((v) => v.id === itemId);
1763
- if (!itemConfig2) return "该物品未配置效果";
1764
- if (itemId === 1e3) {
1765
- const [SentryTower] = await ctx.database.get("ggcevo_boss", { name: "空间站哨枪塔", isActive: true });
1766
- const [record] = await ctx.database.get("ggcevo_sign", { handle });
1767
- const [existingRecord] = await ctx.database.get("ggcevo_boss_damage", { handle });
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
- "ggcevo_boss",
1770
- { name: "空间站哨枪塔" },
1992
+ "ggcevo_equipment",
1993
+ { handle, weaponId: weaponData.id },
1771
1994
  {
1772
- isActive: false,
1773
- HP: 0
1995
+ level: equipment.level + 1,
1996
+ modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
1774
1997
  }
1775
1998
  );
1776
- await ctx.database.upsert("ggcevo_boss_damage", [{
1777
- handle,
1778
- playerName: session.username,
1779
- totalDamage: (existingRecord?.totalDamage || 0) + SentryTower.HP,
1780
- // 改为实际伤害
1781
- attackCount: existingRecord?.attackCount || 0
1782
- }], ["handle"]);
1783
- await ctx.database.upsert("ggcevo_sign", [{
1784
- handle,
1785
- totalRewards: (record?.totalRewards || 0) + SentryTower.HP
1786
- }], ["handle"]);
1787
- return `您使用了E-2能量炸弹,直接摧毁了“空间站哨枪塔”并且获得了${SentryTower.HP}金币。`;
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(applyItemEffect, "applyItemEffect");
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
- points = Math.round(points * 1.5);
2027
- careerMessage = "\n⛏️ 深空矿工职业加成:额外获得50%金币!";
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 + careerMessage + careerCrystalMessage;
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", { guildId: config.ggcqun });
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", { guildId: config.ggcqun }, {
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", { guildId: config.ggcqun });
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", { guildId: config.ggcqun }, {
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", { guildId: config.ggcqun });
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(config.ggcqun, targetUserId);
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 (_, type) => {
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(([_2, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
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/购买武器 <weapon>").action(async ({ session }, weapon) => {
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
- return `❌ 拒绝访问,您已被列入黑名单。`;
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
- if (!weapon) return "如果您想购买武器,请输入“购买武器 武器名称”。";
3500
- if (!weaponConfig[weapon]) return "无效的武器名称,请重新输入。";
3501
- const config2 = weaponConfig[weapon];
3502
- const allowedTypes = ["能量武器", "热能武器", "实弹武器"];
3503
- if (!allowedTypes.includes(config2.type)) {
3504
- return `❌ 无法购买该类型武器,仅支持:${allowedTypes.join("、")}`;
3505
- }
3506
- const existingWeapons = await ctx.database.get("ggcevo_equipment", {
3507
- handle,
3508
- weaponId: config2.id
3509
- });
3510
- if (existingWeapons.length > 0) {
3511
- return `你已经拥有${weapon},无法重复购买。`;
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
- actualPrice = Math.floor(config2.price * 0.8);
3525
- discountMessage = ` (祈愿优惠价,原价${config2.price})`;
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
- return `金币不足,需要${actualPrice}枚金币${discountMessage}`;
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
- await ctx.database.upsert("ggcevo_equipment", [{
3540
- handle,
3541
- weaponId: config2.id,
3542
- level: 0,
3543
- modificationSlots: 1,
3544
- equipped: false
3545
- }], ["handle", "weaponId"]);
3546
- equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
3547
- if (equippedCount === 0) {
3548
- await ctx.database.set(
3549
- "ggcevo_equipment",
3550
- { handle, weaponId: config2.id },
3551
- { equipped: true }
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 = `成功购买 ${weapon}!花费 ${actualPrice}枚金币${discountMessage}。`;
3556
- if (activeWish) {
3557
- message += `
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 (equippedCount === 0) {
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 + "\n输入“武器仓库”查看你拥有的武器。";
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/装备武器 <weapon>").action(async ({ session }, weapon) => {
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/升级武器 <weapon>", "升级武器伤害").action(async ({ session }, weapon) => {
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
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3637
- if (existingEntries.length > 0) {
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 ((signInfo?.totalRewards || 0) < actualCost)
3663
- return `需要${actualCost}枚金币${discountMessage},当前持有:${signInfo?.totalRewards || 0}。`;
3664
- await ctx.database.withTransaction(async () => {
3665
- await ctx.database.set("ggcevo_sign", { handle }, {
3666
- totalRewards: signInfo.totalRewards - actualCost
3667
- });
3668
- await ctx.database.set("ggcevo_equipment", {
3669
- handle,
3670
- weaponId: weaponConfig[weapon].id
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 `${message}
3690
- 当前等级:${newLevel},伤害:${baseDamage},拥有改装槽:${slots}个。`;
4021
+ return `❌ 未找到 "${target}" 对应的武器或科技`;
3691
4022
  });
3692
- ctx.command("ggcevo/改装武器 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
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 ? `使用「改装武器 ${weapon} 模块名称」安装专属模块` : weapon ? "※ 无效武器名称,请使用「改装武器 武器名称 模块名称」安装模块" : "※ 输入「改装武器 武器名称」查询专属模块\n※ 安装模块:「改装武器 武器名称 模块名称」",
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
- 当前存活的异形:${activeNames || "无"}。`;
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
- `💫 祈愿效果:${effectMessage.join(" | ")}`
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: bossConfig.main.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, factionTips;
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 = Object.values(weaponConfig).reduce((stats, weapon) => {
4423
- stats[weapon.type] = (stats[weapon.type] || 0) + 1;
4424
- return stats;
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 = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
4438
- const infoBlocks = [
4439
- `【${name2}】`,
4440
- `类型:${config2.type}`,
4441
- // 选择性显示伤害值
4442
- ...config2.damage !== 0 ? [`基础伤害:${config2.damage}`] : [],
4443
- `订购价:${config2.redCrystalCost}红晶`
4444
- ];
4445
- if (Object.keys(config2.tagEffects).length > 0) {
4446
- const tagEffectsDesc = Object.entries(config2.tagEffects).map(([tag, mul]) => `▸ 对${tag}目标造成${(mul * 100).toFixed(0)}%伤害`).join("\n");
4447
- infoBlocks.push("特性:", tagEffectsDesc);
4448
- }
4449
- if (config2.effects && config2.effects.trim()) {
4450
- infoBlocks.push(`效果:${config2.effects}`);
4451
- }
4452
- infoBlocks.push(
4453
- config2.description,
4454
- "──────────────"
4455
- );
4456
- return infoBlocks.join("\n");
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
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
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 config2 = weaponConfig[item];
4479
- if (!config2?.redCrystalCost) return "❌ 无效物品名称或该物品不可订购";
4480
- const weaponTypes = ["能量武器", "实弹武器", "热能武器"];
4481
- const isWeapon = weaponTypes.includes(config2.type);
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: config2.id
4883
+ weaponId: itemConfig2.id
4486
4884
  });
4487
- if (existing.length) return "⚠️ 该武器已在仓库中";
4885
+ if (existing.length) return "您已经拥有该武器。";
4488
4886
  }
4489
- const requiredRed = config2.redCrystalCost;
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.upsert("ggcevo_equipment", [{
4896
+ await ctx.database.create("ggcevo_equipment", {
4499
4897
  handle,
4500
- weaponId: config2.id,
4898
+ weaponId: itemConfig2.id,
4501
4899
  level: 0,
4502
4900
  modificationSlots: 1,
4901
+ installedMods: [],
4503
4902
  equipped: false
4504
- }], ["handle", "weaponId"]);
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: config2.id },
4908
+ { handle, weaponId: itemConfig2.id },
4510
4909
  { equipped: true }
4511
4910
  );
4512
4911
  }
4513
4912
  } else {
4514
- const existingItems = await ctx.database.get("ggcevo_warehouse", {
4913
+ const [existing] = await ctx.database.get("ggcevo_warehouse", {
4515
4914
  handle,
4516
- itemId: config2.id
4915
+ itemId: itemConfig2.id
4517
4916
  });
4518
4917
  await ctx.database.upsert("ggcevo_warehouse", [{
4519
4918
  handle,
4520
- itemId: config2.id,
4521
- quantity: (existingItems[0]?.quantity || 0) + 1
4919
+ itemId: itemConfig2.id,
4920
+ quantity: (existing?.quantity || 0) + 1
4522
4921
  }], ["handle", "itemId"]);
4523
4922
  }
4524
4923
  });
4525
4924
  if (isWeapon) {
4526
- const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
4527
- let message = `✅ 成功订购【${item}】!消耗 ${requiredRed}红晶`;
4528
- if (equippedCount === 0) {
4529
- message += "\n已自动装备该武器!";
4530
- }
4531
- return message + '\n输入"武器仓库"查看已有装备';
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 [warehouseData] = await ctx.database.get("ggcevo_warehouse", {
4936
+ const currentStock = await ctx.database.get("ggcevo_warehouse", {
4534
4937
  handle,
4535
- itemId: config2.id
4536
- });
4537
- return `✅ 成功订购【${item}】x1!消耗 ${requiredRed}红晶
4538
- 当前库存:${warehouseData.quantity}
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((item) => item.quantity > 0);
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(weaponConfig).find(
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
- let info = `${itemName} x ${warehouseItem.quantity} | 类型:${itemData.type || "未分类"}`;
4569
- if (itemData.effects?.trim()) info += `
4570
- 功能:${itemData.effects}`;
4571
- return info;
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
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4583
- if (existingEntries.length > 0) {
4584
- return "❌ 拒绝访问,您已被列入黑名单";
4996
+ if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
4997
+ return "⛔ 您已被列入黑名单";
4585
4998
  }
4586
4999
  try {
4587
- const items = await ctx.database.get("ggcevo_warehouse", { handle });
4588
- const targetItem = items.find((warehouseItem) => {
4589
- const entry = Object.entries(weaponConfig).find(
4590
- ([, config2]) => config2.id === warehouseItem.itemId
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
- if (!entry) return false;
4593
- const [itemKey] = entry;
4594
- return itemKey.toLowerCase() === itemName?.toLowerCase();
5005
+ return entry?.[0] === itemName;
4595
5006
  });
4596
- if (!targetItem) return `仓库中不存在 ${itemName} 或物品名称错误`;
4597
- if (targetItem.quantity < 1) return `${itemName} 数量不足`;
4598
- if (targetItem.itemId === 1e3) {
4599
- const [SentryTower] = await ctx.database.get("ggcevo_boss", { name: "空间站哨枪塔", isActive: true });
4600
- if (!SentryTower) return "当前没有“空间站哨枪塔”,无法使用E-2能量炸弹。";
4601
- }
4602
- await ctx.database.set("ggcevo_warehouse", { handle, itemId: targetItem.itemId }, {
4603
- quantity: Math.max(targetItem.quantity - 1, 0)
4604
- });
4605
- const effectResult = await applyItemEffect(session, handle, targetItem.itemId);
4606
- return `使用成功!消耗 ${itemName} ×1
4607
- 剩余数量:${targetItem.quantity - 1}
4608
- ${effectResult}`;
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() {