koishi-plugin-ggcevo-game 1.3.0 → 1.3.2

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 CHANGED
@@ -153,6 +153,7 @@ export interface Boss {
153
153
  tags: string[];
154
154
  skills: string[];
155
155
  Skillcountpoints: number;
156
+ Vulnerability: number;
156
157
  groupId: number;
157
158
  isActive: boolean;
158
159
  respawnTime: Date;
package/lib/index.js CHANGED
@@ -234,6 +234,7 @@ function apply(ctx, config) {
234
234
  skills: { type: "list", initial: [] },
235
235
  // 明确数组元素类型
236
236
  Skillcountpoints: "unsigned",
237
+ Vulnerability: "unsigned",
237
238
  groupId: "unsigned",
238
239
  isActive: "boolean",
239
240
  respawnTime: "timestamp"
@@ -371,12 +372,11 @@ function apply(ctx, config) {
371
372
  "侦查步枪": {
372
373
  id: 7,
373
374
  type: "实弹武器",
374
- damage: 60,
375
+ damage: 50,
375
376
  description: "用于隐秘射击的最佳武器,但是无法穿透护甲",
376
377
  price: 550,
377
378
  redCrystalCost: 10,
378
379
  tagEffects: {
379
- "护盾": 0.5,
380
380
  "轻甲": 0.5,
381
381
  "重甲": 0.2
382
382
  }
@@ -384,7 +384,7 @@ function apply(ctx, config) {
384
384
  "零度之下": {
385
385
  id: 8,
386
386
  type: "热能武器",
387
- damage: 30,
387
+ damage: 25,
388
388
  description: "喷射稳定的液氮恒流,对长时间接触者造成致命的损伤",
389
389
  price: 775,
390
390
  redCrystalCost: 10,
@@ -401,8 +401,19 @@ function apply(ctx, config) {
401
401
  price: 750,
402
402
  redCrystalCost: 10,
403
403
  tagEffects: {
404
- "建筑": 2,
405
- "机械": 1.5
404
+ "机械": 2,
405
+ "建筑": 1.5
406
+ }
407
+ },
408
+ "伽马枪": {
409
+ id: 10,
410
+ type: "能量武器",
411
+ damage: 24,
412
+ description: "一种高度危险性的武器,设计用辐射照射并伤害敌人",
413
+ price: 825,
414
+ redCrystalCost: 15,
415
+ tagEffects: {
416
+ "生物": 1.2
406
417
  }
407
418
  }
408
419
  };
@@ -421,7 +432,7 @@ function apply(ctx, config) {
421
432
  description: "非致命军用炸药",
422
433
  price: 75,
423
434
  redCrystalCost: 0,
424
- effects: "对目标使用后,清空其累计技能计数"
435
+ effects: "对非建筑目标使用后,重置其技能计数"
425
436
  }
426
437
  };
427
438
  const modConfig = {
@@ -577,6 +588,26 @@ function apply(ctx, config) {
577
588
  "结构装甲": {
578
589
  effect: 0,
579
590
  description: "拥有结构装甲,受到的伤害-20%; 若伤害来源于热能武器,则受到的伤害-40%"
591
+ },
592
+ "吸血唾液": {
593
+ effect: 0,
594
+ description: "受到攻击将会获得一层“吸血”,每层“吸血”提供5%的减伤,至多10层"
595
+ },
596
+ "进食": {
597
+ effect: 0,
598
+ description: "当“吸血”层数达到10层时,自身将会消耗所有层数回复20%的最大生命值"
599
+ },
600
+ "嗜血狂暴": {
601
+ effect: 0,
602
+ description: "血量低于50%时,每次受到攻击将会额外叠加一层吸血唾液,并且受到的伤害-20%"
603
+ },
604
+ "吐血": {
605
+ effect: 0,
606
+ description: "当无“吸血”层数时,受到的伤害+10%"
607
+ },
608
+ "辐射": {
609
+ effect: 0,
610
+ description: "受到伽马枪攻击时会积累辐射层数,每层使受到的伤害增加1%"
580
611
  }
581
612
  };
582
613
  const defineBoss = /* @__PURE__ */ __name((config2) => config2, "defineBoss");
@@ -594,7 +625,7 @@ function apply(ctx, config) {
594
625
  {
595
626
  name: "异齿猛兽",
596
627
  type: "子代",
597
- maxHP: 7500,
628
+ maxHP: 5e3,
598
629
  tags: asBossTags(["重甲", "生物", "异形"]),
599
630
  passive: asPassives(["弱化形态", "异形甲壳"])
600
631
  }
@@ -670,6 +701,25 @@ function apply(ctx, config) {
670
701
  passive: asPassives(["岗哨机枪", "结构装甲"])
671
702
  }
672
703
  ]
704
+ }),
705
+ defineBoss({
706
+ main: {
707
+ id: 5,
708
+ name: "吸血蝙蝠-首领",
709
+ type: "主宰",
710
+ maxHP: 1e4,
711
+ tags: asBossTags(["生物", "异形"]),
712
+ passive: asPassives(["吸血唾液", "进食", "吐血", "嗜血狂暴"])
713
+ },
714
+ minions: [
715
+ {
716
+ name: "吸血蝙蝠",
717
+ type: "子代",
718
+ maxHP: 3e3,
719
+ tags: asBossTags(["生物", "异形"]),
720
+ passive: asPassives(["弱化形态", "吸血唾液", "进食", "吐血"])
721
+ }
722
+ ]
673
723
  })
674
724
  ];
675
725
  const spaceStationCrewConfig = [
@@ -713,7 +763,7 @@ function apply(ctx, config) {
713
763
  effect: "升级空间站科技花费的金币是原价的80%",
714
764
  requirements: "将一个空间站科技升至3级或以上",
715
765
  Jobtransfer: true,
716
- costcoins: 3e3
766
+ costcoins: 5e3
717
767
  },
718
768
  {
719
769
  professionName: "总工程师",
@@ -860,25 +910,25 @@ function apply(ctx, config) {
860
910
  level: 2,
861
911
  cost: 1750,
862
912
  description: "提高挖矿效率,每日签到金币奖励+10%",
863
- careerBonus: "深空矿工/情报副官: 每日签到金币奖励+20%,解锁专属“挖矿”权限"
913
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+20%; 解锁太空“挖矿”权限"
864
914
  },
865
915
  {
866
916
  level: 3,
867
917
  cost: 2950,
868
918
  description: "提高挖矿效率,每日签到金币奖励+15%",
869
- careerBonus: "深空矿工/情报副官: 每日签到金币奖励+30%,解锁专属“挖矿”权限,并且挖矿效率提高10%"
919
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+30%; 解锁太空“挖矿”权限"
870
920
  },
871
921
  {
872
922
  level: 4,
873
923
  cost: 4250,
874
924
  description: "提高挖矿效率,每日签到金币奖励+20%",
875
- careerBonus: "深空矿工/情报副官: 每日签到金币奖励+40%,解锁专属“挖矿”权限,并且挖矿效率提高20%"
925
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+40%; 解锁太空“挖矿”权限; 建造矿罗协同挖矿,效率提高20%"
876
926
  },
877
927
  {
878
928
  level: 5,
879
929
  cost: 5375,
880
930
  description: "提高挖矿效率,每日签到金币奖励+25%",
881
- careerBonus: "深空矿工/情报副官: 每日签到金币奖励+50%,解锁专属“挖矿”权限,并且挖矿效率提高30%"
931
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+50%; 解锁太空“挖矿”权限; 建造矿罗协同挖矿,效率提高40%"
882
932
  }
883
933
  ]
884
934
  },
@@ -899,25 +949,45 @@ function apply(ctx, config) {
899
949
  level: 2,
900
950
  cost: 1500,
901
951
  description: "提升空间站武器等级,升级武器享有10%的折扣",
902
- careerBonus: "武器中士/情报副官: 升级武器享有20%的折扣,购买武器享有10%的折扣(非传奇)"
952
+ careerBonus: "武器中士/情报副官: 升级武器享有20%的折扣"
903
953
  },
904
954
  {
905
955
  level: 3,
906
956
  cost: 2550,
907
957
  description: "提升空间站武器等级,升级武器享有15%的折扣",
908
- careerBonus: "武器中士/情报副官: 升级武器享有30%的折扣,购买武器享有15%的折扣(非传奇)"
958
+ careerBonus: "武器中士/情报副官: 升级武器享有30%的折扣; 购买武器享有10%的折扣(非传奇)"
909
959
  },
910
960
  {
911
961
  level: 4,
912
962
  cost: 3950,
913
963
  description: "提升空间站武器等级,升级武器享有20%的折扣",
914
- careerBonus: "武器中士/情报副官: 在升级武器享有40%的折扣,购买武器享有20%的折扣(非传奇)"
964
+ careerBonus: "武器中士/情报副官: 在升级武器享有40%的折扣; 购买武器享有15%的折扣(非传奇)"
915
965
  },
916
966
  {
917
967
  level: 5,
918
968
  cost: 4650,
919
- description: "提升空间站武器等级,升级武器享有25%的折扣,可以以原价购买传奇武器(仅限一把)",
920
- careerBonus: "武器中士/情报副官: 升级武器享有50%的折扣,购买武器享有25%的折扣(非传奇),可以以80%的价格购买传奇武器(仅限一把)"
969
+ description: "提升空间站武器等级,升级武器享有25%的折扣; 解锁购买传奇武器权限(仅限一把)",
970
+ careerBonus: "武器中士/情报副官: 升级武器享有50%的折扣; 购买武器享有20%的折扣(非传奇); 解锁购买传奇武器权限(仅限一把),并且享有20%的折扣"
971
+ }
972
+ ]
973
+ },
974
+ {
975
+ techId: 3,
976
+ techname: "武器升级平台",
977
+ careerNames: ["武器中士", "情报副官"],
978
+ maxLevel: 2,
979
+ levels: [
980
+ {
981
+ level: 1,
982
+ cost: 750,
983
+ description: "重启武器升级站,武器改装通用模块享有5%的折扣",
984
+ careerBonus: "武器中士/情报副官: 武器改装通用模块享有10%的折扣"
985
+ },
986
+ {
987
+ level: 2,
988
+ cost: 1e3,
989
+ description: "重启高级武器改装站,武器改装通用模块享有10%的折扣",
990
+ careerBonus: "武器中士/情报副官: 武器改装通用模块享有20%的折扣,武器改装专属模块享有10%的折扣"
921
991
  }
922
992
  ]
923
993
  }
@@ -1303,7 +1373,7 @@ function apply(ctx, config) {
1303
1373
  skillUpdates,
1304
1374
  messages: [
1305
1375
  `❄️ ${targetBoss.name} 触发【冰霜环绕】,自身回复45%最大生命值(+${healAmount}HP)`,
1306
- `🌪️ 【寒霜地狱】降临!所有存活的主宰和存活的子代将获得30%减伤效果`
1376
+ `🌪️ 【寒霜地狱】降临!主宰和所有存活的子代将获得30%减伤效果`
1307
1377
  ]
1308
1378
  };
1309
1379
  }, "handleFrostSurround"),
@@ -1515,6 +1585,82 @@ function apply(ctx, config) {
1515
1585
  messages: [`🛡️ 【结构装甲】生效:${msg}`]
1516
1586
  };
1517
1587
  }, "handleStructuralArmor"),
1588
+ // 处理吸血相关效果(加法减伤 + 独立增伤)
1589
+ handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss, initialDamage, currentHP, maxHP) {
1590
+ let messages = [];
1591
+ let newDamage = initialDamage;
1592
+ const bloodStacks = targetBoss.Skillcountpoints || 0;
1593
+ let totalReduction = 0;
1594
+ if (targetBoss.skills.includes("吸血唾液")) {
1595
+ totalReduction += bloodStacks * 0.05;
1596
+ }
1597
+ if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
1598
+ totalReduction += 0.2;
1599
+ }
1600
+ if (totalReduction > 0) {
1601
+ newDamage = Math.floor(initialDamage * (1 - totalReduction));
1602
+ messages.push(
1603
+ `🩸 【吸血唾液】生效:当前层数${bloodStacks},下次受到伤害减伤${bloodStacks * 5}%` + (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5 ? `🔥 【嗜血狂暴】生效:血量低于50%触发20%减伤` : "")
1604
+ );
1605
+ }
1606
+ if (targetBoss.skills.includes("吐血") && bloodStacks < 1) {
1607
+ newDamage = Math.floor(newDamage * 1.1);
1608
+ messages.push(`💔 【吐血】生效:无“吸血”层数受到伤害+10%`);
1609
+ }
1610
+ return newDamage !== initialDamage ? { initialDamage: newDamage, messages } : null;
1611
+ }, "handleBloodEffects"),
1612
+ // 处理吸血层数叠加和进食触发
1613
+ handleBloodCount: /* @__PURE__ */ __name(async function(ctx2, targetBoss, currentHP, maxHP) {
1614
+ let messages = [];
1615
+ let updatedHP = currentHP;
1616
+ let newStacks = targetBoss.Skillcountpoints || 0;
1617
+ newStacks += 1;
1618
+ if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
1619
+ newStacks += 1;
1620
+ messages.push(`🔥 【嗜血狂暴】生效:额外叠加1层吸血,当前层数${newStacks}`);
1621
+ }
1622
+ newStacks = Math.min(newStacks, 10);
1623
+ await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: newStacks });
1624
+ if (newStacks >= 10 && targetBoss.skills.includes("进食")) {
1625
+ const heal = Math.floor(maxHP * 0.2);
1626
+ updatedHP = Math.min(currentHP + heal, maxHP);
1627
+ await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: 0 });
1628
+ messages.push(`🍽️ 【进食】生效:回复20%最大生命值(+${heal}HP),层数清零`);
1629
+ }
1630
+ return { updatedHP, messages };
1631
+ }, "handleBloodCount"),
1632
+ // 伽马枪辐射层数处理(攻击后触发)
1633
+ handleGammaRadiation: /* @__PURE__ */ __name(async (ctx2, targetBoss, weaponName) => {
1634
+ if (weaponName !== "伽马枪") return null;
1635
+ const messages = [];
1636
+ const isNewRadiation = !targetBoss.skills.includes("辐射");
1637
+ await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, {
1638
+ skills: isNewRadiation ? [...targetBoss.skills, "辐射"] : targetBoss.skills,
1639
+ Vulnerability: isNewRadiation ? 1 : targetBoss.Vulnerability + 1
1640
+ });
1641
+ const [updatedBoss] = await ctx2.database.get("ggcevo_boss", { name: targetBoss.name });
1642
+ const layerMsg = isNewRadiation ? `☢️ 获得【辐射】效果(当前层数1)` : `☢️ 辐射层数+1`;
1643
+ messages.push(`${targetBoss.name} ${layerMsg}`);
1644
+ return { messages };
1645
+ }, "handleGammaRadiation"),
1646
+ // 修正后的辐射伤害计算函数
1647
+ calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss, baseDamage) => {
1648
+ if (!targetBoss.skills.includes("辐射")) {
1649
+ return {
1650
+ damage: baseDamage,
1651
+ messages: []
1652
+ };
1653
+ }
1654
+ const radiationLayers = targetBoss.Vulnerability || 0;
1655
+ const damageMultiplier = 1 + radiationLayers * 0.01;
1656
+ const amplifiedDamage = Math.floor(baseDamage * damageMultiplier);
1657
+ return {
1658
+ damage: amplifiedDamage,
1659
+ messages: radiationLayers > 0 ? [
1660
+ `☢️ 【辐射】生效:当前${radiationLayers}层辐射,受到伤害+${radiationLayers}%`
1661
+ ] : []
1662
+ };
1663
+ }, "calculateRadiationDamage"),
1518
1664
  // 统一处理被动技能(关键修复部分)
1519
1665
  handlePassives: /* @__PURE__ */ __name(async function(ctx2, targetBoss, initialDamage, currentHP, maxHP, weaponName, weaponData, baseDamage, activeBosses, bossGroup) {
1520
1666
  let messages = [];
@@ -1522,6 +1668,18 @@ function apply(ctx, config) {
1522
1668
  if (currentHP <= 0 && !targetBoss.skills.includes("求生本能I") && !targetBoss.skills.includes("求生本能II")) {
1523
1669
  return { currentHP, messages: [], skillUpdates: [], initialDamage };
1524
1670
  }
1671
+ if (weaponName === "伽马枪" && targetBoss.tags.includes("生物") && !targetBoss.tags.includes("机械")) {
1672
+ const radiationCalc = this.calculateRadiationDamage(targetBoss, initialDamage);
1673
+ if (radiationCalc.messages.length > 0) {
1674
+ messages.push(...radiationCalc.messages);
1675
+ initialDamage = radiationCalc.damage;
1676
+ }
1677
+ }
1678
+ const bloodEffectResult = this.handleBloodEffects(targetBoss, initialDamage, currentHP, maxHP);
1679
+ if (bloodEffectResult) {
1680
+ initialDamage = bloodEffectResult.initialDamage;
1681
+ messages.push(...bloodEffectResult.messages);
1682
+ }
1525
1683
  const frostEvoResult = this.handleFrostEvolution(targetBoss, weaponName, baseDamage, currentHP, maxHP);
1526
1684
  if (frostEvoResult) {
1527
1685
  initialDamage = frostEvoResult.initialDamage;
@@ -1552,11 +1710,10 @@ function apply(ctx, config) {
1552
1710
  messages.push(...coldImmunityResult.messages);
1553
1711
  return { currentHP, messages, skillUpdates, initialDamage };
1554
1712
  }
1555
- const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
1556
- if (survivalResult) {
1557
- currentHP = survivalResult.updatedHP;
1558
- messages.push(...survivalResult.messages);
1559
- skillUpdates.push(...survivalResult.skillUpdates);
1713
+ const bloodCountResult = await this.handleBloodCount(ctx2, targetBoss, currentHP, maxHP);
1714
+ if (bloodCountResult) {
1715
+ currentHP = bloodCountResult.updatedHP;
1716
+ messages.push(...bloodCountResult.messages);
1560
1717
  }
1561
1718
  const infectionResult = await this.handleInfectedStation(ctx2, targetBoss, initialDamage, bossGroup);
1562
1719
  if (infectionResult) {
@@ -1576,6 +1733,18 @@ function apply(ctx, config) {
1576
1733
  if (moldResult) {
1577
1734
  messages.push(...moldResult.messages);
1578
1735
  }
1736
+ if (weaponName === "伽马枪" && targetBoss.tags.includes("生物") && !targetBoss.tags.includes("机械")) {
1737
+ const radiationResult = await this.handleGammaRadiation(ctx2, targetBoss, weaponName);
1738
+ if (radiationResult) {
1739
+ messages.push(...radiationResult.messages);
1740
+ }
1741
+ }
1742
+ const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
1743
+ if (survivalResult) {
1744
+ currentHP = survivalResult.updatedHP;
1745
+ messages.push(...survivalResult.messages);
1746
+ skillUpdates.push(...survivalResult.skillUpdates);
1747
+ }
1579
1748
  return { currentHP, messages, skillUpdates, initialDamage };
1580
1749
  }, "handlePassives"),
1581
1750
  // 应用技能更新到数据库
@@ -1902,15 +2071,15 @@ function apply(ctx, config) {
1902
2071
  if (itemConfig2.id === 2) {
1903
2072
  if (!target) return {
1904
2073
  success: false,
1905
- message: "该武器使用需要选择合适的目标。"
2074
+ message: "您未选择合适的目标。"
1906
2075
  };
1907
2076
  const targetboss = await ctx.database.get("ggcevo_boss", {
1908
2077
  name: target,
1909
2078
  isActive: true
1910
2079
  });
1911
- if (!targetboss.length || targetboss[0].Skillcountpoints === 0) return {
2080
+ if (!targetboss.length || targetboss[0].Skillcountpoints === 0 || targetboss[0].tags.includes("建筑")) return {
1912
2081
  success: false,
1913
- message: "您选择的不是合法目标(目标未存活/目标无技能计数)。"
2082
+ message: "您选择的不是合法目标(目标已死亡/目标的技能计数为0/目标拥有“建筑”标签)。"
1914
2083
  };
1915
2084
  await ctx.database.set(
1916
2085
  "ggcevo_boss",
@@ -1919,7 +2088,7 @@ function apply(ctx, config) {
1919
2088
  );
1920
2089
  return {
1921
2090
  success: true,
1922
- message: `成功使用${itemName},您的目标${target}已重置其技能计数`
2091
+ message: `成功使用 ${itemName},已重置 ${target} 的技能计数`
1923
2092
  };
1924
2093
  }
1925
2094
  return {
@@ -3471,7 +3640,8 @@ ${achievementList.join("\n")}`;
3471
3640
  }),
3472
3641
  `房主: ${lobby.hostName}`,
3473
3642
  `玩家数: ${lobby.slotsHumansTaken}/${lobby.slotsHumansTotal}`,
3474
- `🏆 安全玩家:${atElements || ""}`
3643
+ "──────────────",
3644
+ `请以下玩家通知房主踢人:${atElements || "无"}`
3475
3645
  ].join("\n");
3476
3646
  const groupId = [...config.groupId];
3477
3647
  await ctx.broadcast(groupId, message);
@@ -3751,6 +3921,16 @@ ${achievementList.join("\n")}`;
3751
3921
  ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async ({ session }, type) => {
3752
3922
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3753
3923
  if (!profile) return "⚠️ 需要先绑定游戏句柄";
3924
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3925
+ const [techData] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 }).catch(() => [{ level: 0 }]);
3926
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
3927
+ const techLevel = techData?.level || 0;
3928
+ const isCareerMatch = Spacestationtechnology.find((t) => t.techId === 2).careerNames.includes(careerData?.career);
3929
+ const BASE_DISCOUNTS = [0, 0, 0, 0, 0];
3930
+ const CAREER_DISCOUNTS = [0, 0, 10, 15, 20];
3931
+ const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
3932
+ const careerDiscount = isCareerMatch ? CAREER_DISCOUNTS[techLevel - 1] : 0;
3933
+ const discountRate = Math.max(baseDiscount, careerDiscount);
3754
3934
  const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
3755
3935
  stats[weapon.type] = (stats[weapon.type] || 0) + 1;
3756
3936
  return stats;
@@ -3761,21 +3941,23 @@ ${achievementList.join("\n")}`;
3761
3941
  '使用 "武器库 类型名称" 查看详细列表',
3762
3942
  "====================",
3763
3943
  ...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
3944
+ discountRate > 0 && `
3945
+ 💡 当前购买折扣:${discountRate}%(武器系统 Lv${techLevel})`,
3764
3946
  "===================="
3765
- ].join("\n");
3947
+ ].filter(Boolean).join("\n");
3766
3948
  }
3767
- const validTypes = Object.keys(typeStats);
3768
- if (!validTypes.includes(type)) {
3949
+ if (!Object.keys(typeStats).includes(type)) {
3769
3950
  return `无效武器类型,可用类型:
3770
- ${validTypes.join("、")}`;
3951
+ ${Object.keys(typeStats).join("、")}`;
3771
3952
  }
3772
3953
  const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
3954
+ const actualPrice = Math.floor(config2.price * (1 - discountRate / 100));
3773
3955
  const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
3774
3956
  return [
3775
3957
  `【${name2}】`,
3776
3958
  `类型:${config2.type}`,
3777
3959
  `基础伤害:${config2.damage}`,
3778
- `价格:${config2.price}金币`,
3960
+ `价格:${actualPrice}金币${discountRate > 0 ? ` (原价${config2.price}, 折扣${discountRate}%)` : ""}`,
3779
3961
  "特性:",
3780
3962
  tagEffectsDesc,
3781
3963
  `描述:${config2.description}`
@@ -3784,10 +3966,11 @@ ${validTypes.join("、")}`;
3784
3966
  return [
3785
3967
  `🏪 咕咕武器库 - ${type} 🏪`,
3786
3968
  "使用“购买 武器名称”命令进行购买",
3969
+ discountRate > 0 && `🔧 当前应用折扣:武器系统 Lv${techLevel} ${discountRate}%`,
3787
3970
  "====================",
3788
3971
  ...items,
3789
3972
  items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
3790
- ].join("\n\n");
3973
+ ].filter(Boolean).join("\n\n");
3791
3974
  });
3792
3975
  ctx.command("ggcevo/爆破库 [type]").usage("输入“爆破库”查看分类,或“爆破库 类型”查看详细物品").action(async ({ session }, type) => {
3793
3976
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
@@ -4043,78 +4226,109 @@ ${validTypes.join("、")}`;
4043
4226
  return `❌ 未找到 "${target}" 对应的武器或科技`;
4044
4227
  });
4045
4228
  ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
4046
- const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
4047
- const generateModList = /* @__PURE__ */ __name(() => {
4048
- if (!isValidWeapon) {
4049
- return Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(formatModEntry).join("\n\n");
4050
- }
4051
- const exclusiveMods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive && m.exclusiveTo === weapon).map(formatModEntry);
4052
- return exclusiveMods.length ? exclusiveMods.join("\n\n") : "该武器暂无专属模块";
4053
- }, "generateModList");
4054
- const formatModEntry = /* @__PURE__ */ __name(([name2, config2]) => [
4055
- `【${name2}】${config2.isExclusive ? ` (专属:${config2.exclusiveTo})` : ""}`,
4056
- `价格:${config2.cost}金币`,
4057
- `效果:${config2.effect.replace(/▸/g, "▸ ")}`,
4058
- config2.isExclusive ? "※ 每个武器只能安装一个专属模块" : ""
4059
- ].filter(Boolean).join("\n"), "formatModEntry");
4060
- if (!mod || !modConfig[mod]) {
4061
- return [
4062
- isValidWeapon ? `🛠️ ${weapon} 专属模块 🛠️` : "🛠️ 通用武器模块 🛠️",
4063
- isValidWeapon ? `使用「改装 ${weapon} 模块名称」安装专属模块` : weapon ? "※ 无效武器名称,请使用「改装 武器名称 模块名称」安装模块" : "※ 输入「改装 武器名称」查询专属模块\n※ 安装模块:「改装 武器名称 模块名称」",
4064
- "====================",
4065
- generateModList()
4066
- ].join("\n\n");
4067
- }
4068
4229
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4069
4230
  if (!profile) return "您暂未绑定句柄";
4070
4231
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4071
4232
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4072
- if (existingEntries.length > 0) {
4073
- return `❌ 拒绝访问,您已被列入黑名单。`;
4074
- }
4075
- const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
4076
- const [equipment] = await ctx.database.get("ggcevo_equipment", {
4077
- handle,
4078
- weaponId: weaponConfig[weapon].id
4079
- });
4080
- if (!equipment) return "尚未获得该武器。";
4081
- const modInfo = modConfig[mod];
4082
- if (modInfo.isExclusive) {
4083
- if (modInfo.exclusiveTo !== weapon) {
4084
- return `❌ 该模块只能安装在${modInfo.exclusiveTo}上。`;
4233
+ if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单";
4234
+ const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
4235
+ const processModInstallation = /* @__PURE__ */ __name(async () => {
4236
+ const modInfo = modConfig[mod];
4237
+ if (!modInfo) return "无效模块名称。";
4238
+ const [equipment] = await ctx.database.get("ggcevo_equipment", {
4239
+ handle,
4240
+ weaponId: weaponConfig[weapon].id
4241
+ });
4242
+ if (!equipment) return "尚未获得该武器。";
4243
+ if (modInfo.isExclusive) {
4244
+ if (modInfo.exclusiveTo !== weapon) return `❌ 该模块只能安装在${modInfo.exclusiveTo}上。`;
4245
+ const hasExclusive = equipment.installedMods.some((m) => modConfig[m]?.isExclusive);
4246
+ if (hasExclusive) return "❌ 每个武器只能安装一个专属模块。";
4085
4247
  }
4086
- const hasExclusive = equipment.installedMods.some((m) => modConfig[m]?.isExclusive);
4087
- if (hasExclusive) return "❌ 每个武器只能安装一个专属模块。";
4088
- }
4089
- if (equipment.installedMods.length >= equipment.modificationSlots)
4090
- return "当前武器改装槽已满(升级武器等级至3/6级的时候会额外获得一个改装槽)。";
4091
- if (equipment.installedMods.includes(mod))
4092
- return "当前武器已安装相同模块。";
4093
- if ((signInfo?.totalRewards || 0) < modInfo.cost)
4094
- return `需要${modInfo.cost}枚金币,当前持有:${signInfo?.totalRewards || 0}`;
4095
- await ctx.database.set("ggcevo_equipment", {
4096
- handle,
4097
- weaponId: weaponConfig[weapon].id
4098
- }, {
4099
- installedMods: [...equipment.installedMods, mod]
4100
- });
4101
- await ctx.database.set("ggcevo_sign", { handle }, {
4102
- totalRewards: signInfo.totalRewards - modInfo.cost
4103
- });
4104
- const installedModsList = [...equipment.installedMods, mod].map((m) => {
4105
- const config2 = modConfig[m];
4248
+ if (equipment.installedMods.length >= equipment.modificationSlots) {
4249
+ return "❌ 当前可用改装槽已满(武器升级至3/6级会额外获得一个改装槽)。";
4250
+ }
4251
+ if (equipment.installedMods.includes(mod)) {
4252
+ return "❌ 已安装相同模块。";
4253
+ }
4254
+ const [techData] = await ctx.database.get("ggcevo_tech", { handle, techId: 3 }).catch(() => [{ level: 0 }]);
4255
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4256
+ const techLevel = techData?.level || 0;
4257
+ const isCareerMatch = Spacestationtechnology.find((t) => t.techId === 3).careerNames.includes(careerData?.career);
4258
+ let discountRate = 0;
4259
+ if (modInfo.isExclusive) {
4260
+ if (techLevel >= 2 && isCareerMatch) discountRate = 10;
4261
+ } else {
4262
+ const baseDiscount = [5, 10][techLevel - 1] || 0;
4263
+ const careerDiscount = techLevel >= 1 && isCareerMatch ? [10, 20][techLevel - 1] : 0;
4264
+ discountRate = Math.max(baseDiscount, careerDiscount);
4265
+ }
4266
+ const actualCost = Math.floor(modInfo.cost * (1 - discountRate / 100));
4267
+ const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
4268
+ if ((signInfo?.totalRewards || 0) < actualCost) {
4269
+ return `需要 ${actualCost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
4270
+ }
4271
+ await ctx.database.set(
4272
+ "ggcevo_equipment",
4273
+ { handle, weaponId: weaponConfig[weapon].id },
4274
+ { installedMods: [...equipment.installedMods, mod] }
4275
+ );
4276
+ await ctx.database.set("ggcevo_sign", { handle }, {
4277
+ totalRewards: signInfo.totalRewards - actualCost
4278
+ });
4279
+ const discountMsg = discountRate > 0 ? `武器升级平台 Lv${techLevel} 折扣:${discountRate}%` : "";
4106
4280
  return [
4107
- `【${m}】`,
4108
- `安装费用:${config2.cost}枚金币`,
4109
- `效果:${config2.effect}`
4281
+ `✅ ${weapon} 成功安装 ${mod}!`,
4282
+ discountMsg,
4283
+ `花费金币:${actualCost}`,
4284
+ `改装槽:${equipment.installedMods.length + 1}/${equipment.modificationSlots}`
4110
4285
  ].join("\n");
4111
- }).join("\n\n");
4112
- return [
4113
- `✅ ${weapon} 成功安装 ${mod}!`,
4114
- "当前改装配置:",
4115
- installedModsList,
4116
- `剩余金币:${signInfo.totalRewards - modInfo.cost}`
4117
- ].join("\n\n");
4286
+ }, "processModInstallation");
4287
+ const showModList = /* @__PURE__ */ __name(async () => {
4288
+ const [techData] = await ctx.database.get("ggcevo_tech", { handle, techId: 3 }).catch(() => [{ level: 0 }]);
4289
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4290
+ const techLevel = techData?.level || 0;
4291
+ const isCareerMatch = Spacestationtechnology.find((t) => t.techId === 3).careerNames.includes(careerData?.career);
4292
+ const formatMod = /* @__PURE__ */ __name((name2, config2) => {
4293
+ let discountRate = 0;
4294
+ if (config2.isExclusive) {
4295
+ if (techLevel >= 2 && isCareerMatch) discountRate = 10;
4296
+ } else {
4297
+ const baseDiscount = [5, 10][techLevel - 1] || 0;
4298
+ const careerDiscount = techLevel >= 1 && isCareerMatch ? [10, 20][techLevel - 1] : 0;
4299
+ discountRate = Math.max(baseDiscount, careerDiscount);
4300
+ }
4301
+ const actualPrice = Math.floor(config2.cost * (1 - discountRate / 100));
4302
+ return [
4303
+ `【${name2}】${config2.isExclusive ? ` (专属:${config2.exclusiveTo})` : ""}`,
4304
+ `价格:${actualPrice}金币${discountRate > 0 ? ` (原价${config2.cost}, 折扣${discountRate}%)` : ""}`,
4305
+ `效果:${config2.effect.replace(/▸/g, "▸ ")}`,
4306
+ config2.isExclusive ? "※ 每个武器只能安装一个专属模块" : ""
4307
+ ].filter(Boolean).join("\n");
4308
+ }, "formatMod");
4309
+ if (isValidWeapon) {
4310
+ const exclusiveMods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive && m.exclusiveTo === weapon).map(([name2, cfg]) => formatMod(name2, cfg));
4311
+ return [
4312
+ `🛠️ ${weapon} 专属模块 🛠️`,
4313
+ "使用「改装 武器名称 模块名称」安装",
4314
+ "====================",
4315
+ exclusiveMods.length ? exclusiveMods.join("\n\n") : "该武器暂无专属模块"
4316
+ ].join("\n\n");
4317
+ } else {
4318
+ const universalMods = Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(([name2, cfg]) => formatMod(name2, cfg));
4319
+ return [
4320
+ "🛠️ 通用武器模块 🛠️",
4321
+ "使用「改装 武器名称 模块名称」安装专属模块",
4322
+ "====================",
4323
+ universalMods.join("\n\n")
4324
+ ].join("\n\n");
4325
+ }
4326
+ }, "showModList");
4327
+ if (mod) {
4328
+ return processModInstallation();
4329
+ } else {
4330
+ return showModList();
4331
+ }
4118
4332
  });
4119
4333
  ctx.command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
4120
4334
  const session = argv.session;
@@ -5114,6 +5328,9 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5114
5328
  return "⛔ 您已被列入黑名单";
5115
5329
  }
5116
5330
  const [career] = await ctx.database.get("ggcevo_careers", { handle });
5331
+ if (!career || career.group !== "人类联盟") {
5332
+ return "🚫 该功能需要【人类联盟】阵营权限";
5333
+ }
5117
5334
  if (!["深空矿工", "情报副官"].includes(career?.career)) {
5118
5335
  return "🚫 需要职业为深空矿工或情报副官";
5119
5336
  }
@@ -5129,8 +5346,9 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5129
5346
  });
5130
5347
  return "⛏️ 挖矿作业已开始,至少1小时后可收获";
5131
5348
  }
5349
+ const nowtime = /* @__PURE__ */ new Date();
5132
5350
  const chinaStart = convertUTCtoChinaTime2(record.startTime);
5133
- const chinaNow = convertUTCtoChinaTime2(/* @__PURE__ */ new Date());
5351
+ const chinaNow = convertUTCtoChinaTime2(nowtime);
5134
5352
  const duration = Math.floor(
5135
5353
  (chinaNow.getTime() - chinaStart.getTime()) / 1e3 / 60
5136
5354
  );
@@ -5138,8 +5356,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5138
5356
  const remaining = 60 - duration;
5139
5357
  return [
5140
5358
  "⛏️ 挖矿进行中",
5141
- `🕒 开始时间:${chinaStart.toLocaleString("zh-CN", { hour12: false })}`,
5142
- `⏱️ 当前时间:${chinaNow.toLocaleString("zh-CN", { hour12: false })}`,
5359
+ `🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
5360
+ `⏱️ 当前时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
5143
5361
  `⏳ 还需等待:${remaining}分钟`,
5144
5362
  `💡 提示:达到1小时可随时收获并自动开始下一轮`
5145
5363
  ].join("\n");
@@ -5150,16 +5368,12 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5150
5368
  base = Math.min(base, 300);
5151
5369
  let multiplier = 0;
5152
5370
  switch (tech.level) {
5153
- case 3:
5154
- multiplier = 0.1;
5155
- break;
5156
- // +10%
5157
5371
  case 4:
5158
- multiplier = 0.3;
5372
+ multiplier = 0.2;
5159
5373
  break;
5160
- // +30%
5374
+ // +20%
5161
5375
  case 5:
5162
- multiplier = 0.5;
5376
+ multiplier = 0.4;
5163
5377
  break;
5164
5378
  }
5165
5379
  const total = Math.round(base * (1 + multiplier));
@@ -5180,8 +5394,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
5180
5394
  }, "formatTime");
5181
5395
  return [
5182
5396
  "⛏️ 挖矿报告",
5183
- `🕒 开始时间:${chinaStart.toLocaleString("zh-CN", { hour12: false })}`,
5184
- `⏱️ 结束时间:${chinaNow.toLocaleString("zh-CN", { hour12: false })}`,
5397
+ `🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
5398
+ `⏱️ 结束时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
5185
5399
  `⏳ 持续时间:${formatTime(duration)}`,
5186
5400
  ...tech.level >= 3 ? (
5187
5401
  // 仅当科技等级≥3时显示加成信息
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ggcevo-game",
3
3
  "description": "《星际争霸2》咕咕虫-evolved地图的专属游戏助手插件,集成天梯排行、抽奖系统、签到福利、兑换商城等丰富功能。",
4
- "version": "1.3.0",
4
+ "version": "1.3.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [