koishi-plugin-ggcevo-game 1.2.72 → 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.
Files changed (2) hide show
  1. package/lib/index.js +556 -191
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -408,6 +408,14 @@ function apply(ctx, config) {
408
408
  price: 0,
409
409
  redCrystalCost: 30,
410
410
  effects: "当主宰为“空间站感染虫”时才能使用,对“空间站哨枪塔”造成其当前血量值的伤害(获得等同于伤害值的金币)"
411
+ },
412
+ "闪光弹": {
413
+ id: 2,
414
+ type: "手榴弹",
415
+ description: "非致命军用炸药",
416
+ price: 75,
417
+ redCrystalCost: 0,
418
+ effects: "对目标使用后,清空其累计技能计数"
411
419
  }
412
420
  };
413
421
  const modConfig = {
@@ -696,7 +704,7 @@ function apply(ctx, config) {
696
704
  },
697
705
  {
698
706
  professionName: "情报副官",
699
- effect: "升级联盟空间站科技享有80%的折扣",
707
+ effect: "",
700
708
  requirements: "拥有500枚金币",
701
709
  Jobtransfer: false,
702
710
  costcoins: 3e3
@@ -749,7 +757,7 @@ function apply(ctx, config) {
749
757
  },
750
758
  {
751
759
  professionName: "枪手",
752
- effect: "武器等级上限为7级,升级武器享有80%的折扣(可与祈愿叠加)",
760
+ effect: "武器等级上限为7",
753
761
  requirements: "拥有2把武器等级为6的武器",
754
762
  Jobtransfer: false,
755
763
  costcoins: 0,
@@ -832,74 +840,78 @@ function apply(ctx, config) {
832
840
  {
833
841
  techId: 1,
834
842
  techname: "采掘系统",
843
+ careerNames: ["深空矿工", "情报副官"],
844
+ // 新增职业名称字段
835
845
  maxLevel: 5,
836
846
  levels: [
837
847
  {
838
848
  level: 1,
839
849
  cost: 500,
840
- description: "提高挖矿效率,每日签到奖励+5%",
841
- careerBonus: "深空矿工/情报副官: 每日签到奖励+10%"
850
+ description: "提高挖矿效率,每日签到金币奖励+5%",
851
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+10%"
842
852
  },
843
853
  {
844
854
  level: 2,
845
855
  cost: 1750,
846
- description: "提高挖矿效率,每日签到奖励+10%",
847
- careerBonus: "深空矿工/情报副官: 每日签到奖励+20%,解锁专属“挖矿”指令"
856
+ description: "提高挖矿效率,每日签到金币奖励+10%",
857
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+20%,解锁专属“挖矿”权限"
848
858
  },
849
859
  {
850
860
  level: 3,
851
861
  cost: 2950,
852
- description: "提高挖矿效率,每日签到奖励+15%",
853
- careerBonus: "深空矿工/情报副官: 每日签到奖励+30%,解锁专属“挖矿”指令"
862
+ description: "提高挖矿效率,每日签到金币奖励+15%",
863
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+30%,解锁专属“挖矿”权限,并且挖矿效率提高10%"
854
864
  },
855
865
  {
856
866
  level: 4,
857
867
  cost: 4250,
858
- description: "提高挖矿效率,每日签到奖励+20%",
859
- careerBonus: "深空矿工/情报副官: 每日签到奖励+40%,解锁专属“挖矿”指令,并且挖矿效率提高25%"
868
+ description: "提高挖矿效率,每日签到金币奖励+20%",
869
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+40%,解锁专属“挖矿”权限,并且挖矿效率提高20%"
860
870
  },
861
871
  {
862
872
  level: 5,
863
873
  cost: 5375,
864
- description: "提高挖矿效率,每日签到奖励+25%",
865
- careerBonus: "深空矿工/情报副官: 每日签到奖励+50%,解锁专属“挖矿”指令,并且挖矿效率提高50%"
874
+ description: "提高挖矿效率,每日签到金币奖励+25%",
875
+ careerBonus: "深空矿工/情报副官: 每日签到金币奖励+50%,解锁专属“挖矿”权限,并且挖矿效率提高30%"
866
876
  }
867
877
  ]
868
878
  },
869
879
  {
870
880
  techId: 2,
871
881
  techname: "武器系统",
882
+ careerNames: ["武器中士", "情报副官"],
883
+ // 新增职业名称字段
872
884
  maxLevel: 5,
873
885
  levels: [
874
886
  {
875
887
  level: 1,
876
888
  cost: 500,
877
- description: "提升空间站武器等级,升级/改装武器享有5%的折扣",
878
- careerBonus: "武器中士/情报副官: 升级/改装武器享有10%的折扣"
889
+ description: "提升空间站武器等级,升级武器享有5%的折扣",
890
+ careerBonus: "武器中士/情报副官: 升级武器享有10%的折扣"
879
891
  },
880
892
  {
881
893
  level: 2,
882
894
  cost: 1500,
883
- description: "提升空间站武器等级,升级/改装武器享有10%的折扣",
884
- careerBonus: "武器中士/情报副官: 升级/改装武器享有20%的折扣,购买武器享有10%的折扣(非传奇)"
895
+ description: "提升空间站武器等级,升级武器享有10%的折扣",
896
+ careerBonus: "武器中士/情报副官: 升级武器享有20%的折扣,购买武器享有10%的折扣(非传奇)"
885
897
  },
886
898
  {
887
899
  level: 3,
888
900
  cost: 2550,
889
- description: "提升空间站武器等级,升级/改装武器享有15%的折扣",
890
- careerBonus: "武器中士/情报副官: 升级/改装武器享有30%的折扣,购买武器享有15%的折扣(非传奇)"
901
+ description: "提升空间站武器等级,升级武器享有15%的折扣",
902
+ careerBonus: "武器中士/情报副官: 升级武器享有30%的折扣,购买武器享有15%的折扣(非传奇)"
891
903
  },
892
904
  {
893
905
  level: 4,
894
906
  cost: 3950,
895
- description: "提升空间站武器等级,升级/改装武器享有20%的折扣",
896
- careerBonus: "武器中士/情报副官: 在升级/改装武器享有40%的折扣,购买武器享有20%的折扣(非传奇)"
907
+ description: "提升空间站武器等级,升级武器享有20%的折扣",
908
+ careerBonus: "武器中士/情报副官: 在升级武器享有40%的折扣,购买武器享有20%的折扣(非传奇)"
897
909
  },
898
910
  {
899
911
  level: 5,
900
912
  cost: 4650,
901
- description: "提升空间站武器等级,升级/改装武器享有25%的折扣,可以以原价购买传奇武器(仅限一把)",
902
- careerBonus: "武器中士/情报副官: 升级/改装武器享有50%的折扣,购买武器享有25%的折扣(非传奇),可以以80%的价格购买传奇武器(仅限一把)"
913
+ description: "提升空间站武器等级,升级武器享有25%的折扣,可以以原价购买传奇武器(仅限一把)",
914
+ careerBonus: "武器中士/情报副官: 升级武器享有50%的折扣,购买武器享有25%的折扣(非传奇),可以以80%的价格购买传奇武器(仅限一把)"
903
915
  }
904
916
  ]
905
917
  }
@@ -932,31 +944,25 @@ function apply(ctx, config) {
932
944
  return { totalModAdd, hasCrit };
933
945
  }
934
946
  __name(calculateModifiers, "calculateModifiers");
935
- async function calculateTagMultiplier(weaponData, bossName, equippedWeapon) {
936
- const bossRecord = await ctx.database.get("ggcevo_boss", { name: bossName });
937
- if (!bossRecord || !bossRecord.length) {
938
- throw new Error(`未找到BOSS记录: ${bossName}`);
939
- }
940
- 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
+ ];
941
952
  let totalAdditive = 0;
942
- bossTags.forEach((tag) => {
943
- let effectValue;
944
- if (tag === "重甲" && equippedWeapon.installedMods.includes("裂甲核心")) {
945
- effectValue = 1.2;
946
- } else if (tag === "惧热" && equippedWeapon.installedMods.includes("助燃核心")) {
947
- effectValue = 4;
948
- } else {
949
- effectValue = weaponData.tagEffects?.[tag] ?? 1;
950
- }
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;
951
958
  totalAdditive += effectValue - 1;
952
- });
959
+ }
953
960
  return totalAdditive;
954
961
  }
955
962
  __name(calculateTagMultiplier, "calculateTagMultiplier");
956
- function calculatePassiveEffects(targetBoss) {
963
+ function calculatePassiveEffects(passives) {
957
964
  let passiveEffect = 0;
958
- const effectivePassives = [...targetBoss.skills || []];
959
- effectivePassives.forEach((passive) => {
965
+ passives.forEach((passive) => {
960
966
  const effect = passiveConfig[passive]?.effect || 0;
961
967
  passiveEffect += effect;
962
968
  });
@@ -1003,8 +1009,10 @@ function apply(ctx, config) {
1003
1009
  return Math.floor(rankRecord.rank / 400) * 0.01;
1004
1010
  }
1005
1011
  __name(calculateRankBonus, "calculateRankBonus");
1006
- async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss) {
1012
+ async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss, options) {
1007
1013
  let effectMessage = [];
1014
+ const finalTags = options?.customTags || targetBoss.tags || [];
1015
+ const finalPassives = options?.customPassives || targetBoss.skills || [];
1008
1016
  const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
1009
1017
  const { regionId, realmId, profileId } = profile;
1010
1018
  const handle = `${regionId}-S2-${realmId}-${profileId}`;
@@ -1027,10 +1035,9 @@ function apply(ctx, config) {
1027
1035
  if (critRhythmEffect) {
1028
1036
  effectMessage.push("🎵 暴击韵律祈愿生效(暴击率+20%)");
1029
1037
  }
1030
- const targetBossConfig = targetBoss.name;
1031
- const tagMultiplier = await calculateTagMultiplier(weaponData, targetBossConfig, equippedWeapon);
1038
+ const tagMultiplier = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
1032
1039
  damage *= 1 + tagMultiplier;
1033
- const passiveMultiplier = calculatePassiveEffects(targetBoss);
1040
+ const passiveMultiplier = calculatePassiveEffects(finalPassives);
1034
1041
  damage *= 1 + passiveMultiplier;
1035
1042
  const { damage: careerDamage, message: careerMessage } = await calculateCareerBonus(
1036
1043
  ctx2,
@@ -1835,12 +1842,20 @@ function apply(ctx, config) {
1835
1842
  }
1836
1843
  }
1837
1844
  __name(checkTransferRequirements, "checkTransferRequirements");
1838
- async function applyItemEffect(session, handle, itemConfig2) {
1839
- const itemName = Object.entries(SyndicatedItems).find(
1840
- ([_, item]) => item.id === itemConfig2.id
1841
- )?.[0] || "未知物品";
1845
+ async function applyItemEffect(session, handle, itemConfig2, target) {
1842
1846
  try {
1847
+ const itemName = Object.entries(SyndicatedItems).find(
1848
+ ([_, item]) => item.id === itemConfig2.id
1849
+ )?.[0] || "未知物品";
1843
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
+ };
1844
1859
  const [SentryTower] = await ctx.database.get("ggcevo_boss", {
1845
1860
  name: "空间站哨枪塔",
1846
1861
  isActive: true
@@ -1849,39 +1864,179 @@ function apply(ctx, config) {
1849
1864
  await ctx.database.set(
1850
1865
  "ggcevo_boss",
1851
1866
  { name: "空间站哨枪塔" },
1852
- {
1853
- isActive: false,
1854
- HP: 0
1855
- }
1867
+ { isActive: false, HP: 0 }
1856
1868
  );
1857
1869
  await ctx.database.withTransaction(async () => {
1858
1870
  const signRecords = await ctx.database.get("ggcevo_sign", { handle });
1859
- const currentRewards = signRecords[0]?.totalRewards || 0;
1860
1871
  await ctx.database.upsert("ggcevo_sign", [{
1861
1872
  handle,
1862
- totalRewards: currentRewards + damageValue
1873
+ totalRewards: (signRecords[0]?.totalRewards || 0) + damageValue
1863
1874
  }], ["handle"]);
1864
1875
  const damageRecords = await ctx.database.get("ggcevo_boss_damage", { handle });
1865
- const currentDamage = damageRecords[0]?.totalDamage || 0;
1866
- const currentCount = damageRecords[0]?.attackCount || 0;
1867
1876
  await ctx.database.upsert("ggcevo_boss_damage", [{
1868
1877
  handle,
1869
1878
  playerName: session.username,
1870
- totalDamage: currentDamage + damageValue,
1871
- attackCount: currentCount,
1872
- // 保持原攻击次数
1879
+ totalDamage: (damageRecords[0]?.totalDamage || 0) + damageValue,
1880
+ attackCount: damageRecords[0]?.attackCount || 0,
1873
1881
  bossGroupId: 4
1874
1882
  }], ["handle"]);
1875
1883
  });
1876
- return `成功引爆${itemName},造成 ${damageValue} 点伤害,获得等额金币`;
1884
+ return {
1885
+ success: true,
1886
+ message: `成功引爆${itemName},造成 ${damageValue} 点伤害,获得等额金币`
1887
+ };
1877
1888
  }
1878
- return `${itemName} 效果已生效(开发中)`;
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
+ };
1879
1916
  } catch (error) {
1880
1917
  console.error("物品效果处理失败:", error);
1881
- return "⚠️ 物品效果处理异常,已回滚操作";
1918
+ return {
1919
+ success: false,
1920
+ message: "⚠️ 物品效果处理异常,已回滚操作"
1921
+ };
1882
1922
  }
1883
1923
  }
1884
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
+ });
1991
+ await ctx.database.set(
1992
+ "ggcevo_equipment",
1993
+ { handle, weaponId: weaponData.id },
1994
+ {
1995
+ level: equipment.level + 1,
1996
+ modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
1997
+ }
1998
+ );
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%");
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;
2028
+ }
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");
1885
2040
  ctx.command("ggcevo/抽奖").action(async (argv) => {
1886
2041
  const session = argv.session;
1887
2042
  let winCount = 0;
@@ -2109,17 +2264,41 @@ ${itemDetails.join("\n")}`;
2109
2264
  }
2110
2265
  let redCrystal = 0;
2111
2266
  let careerCrystalMessage = "";
2112
- if (meowEffect) {
2113
- tickets *= 2;
2114
- points *= 2;
2115
- effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励!";
2116
- }
2117
- let careerMessage = "";
2118
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 = "";
2119
2292
  if (careerData?.career === "深空矿工") {
2120
- points = Math.round(points * 1.5);
2121
- careerMessage = "\n⛏️ 深空矿工职业加成:额外获得50%金币!";
2293
+ minerBonus = 50;
2294
+ minerMessage = `
2295
+ ⛏️ 深空矿工职业加成:金币+50%`;
2122
2296
  }
2297
+ const totalBonus = miningBonus + minerBonus;
2298
+ if (totalBonus > 0) {
2299
+ points = Math.round(points * (1 + totalBonus / 100));
2300
+ }
2301
+ const bonusMessage = miningMessage + minerMessage;
2123
2302
  if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
2124
2303
  if (monthlyDays < 7) {
2125
2304
  redCrystal = 1;
@@ -2135,6 +2314,11 @@ ${itemDetails.join("\n")}`;
2135
2314
  careerCrystalMessage = `
2136
2315
  ⚓ 辛迪加财务经理职业加成:获得 ${redCrystal} 红晶`;
2137
2316
  }
2317
+ if (meowEffect) {
2318
+ tickets *= 2;
2319
+ points *= 2;
2320
+ effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励(金币和咕咕币)!";
2321
+ }
2138
2322
  await ctx.database.withTransaction(async () => {
2139
2323
  await ctx.database.upsert("ggcevo_sign", [{
2140
2324
  handle,
@@ -2156,7 +2340,7 @@ ${itemDetails.join("\n")}`;
2156
2340
  });
2157
2341
  return `签到成功!本月累计签到${monthlyDays}天,获得:
2158
2342
  💰 金币 x ${points}
2159
- 🪙 咕咕币 x ${tickets}` + effectMessage + careerMessage + careerCrystalMessage;
2343
+ 🪙 咕咕币 x ${tickets}` + (effectMessage || "") + bonusMessage + (careerCrystalMessage || "");
2160
2344
  } catch (error) {
2161
2345
  console.error("签到命令时发生错误:", error);
2162
2346
  return "服务器繁忙,请稍后尝试。";
@@ -3542,7 +3726,9 @@ ${achievementList.join("\n")}`;
3542
3726
  day: "2-digit"
3543
3727
  })}`;
3544
3728
  });
3545
- 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 "⚠️ 需要先绑定游戏句柄";
3546
3732
  const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
3547
3733
  stats[weapon.type] = (stats[weapon.type] || 0) + 1;
3548
3734
  return stats;
@@ -3561,7 +3747,7 @@ ${achievementList.join("\n")}`;
3561
3747
  return `无效武器类型,可用类型:
3562
3748
  ${validTypes.join("、")}`;
3563
3749
  }
3564
- 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]) => {
3565
3751
  const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
3566
3752
  return [
3567
3753
  `【${name2}】`,
@@ -3581,46 +3767,115 @@ ${validTypes.join("、")}`;
3581
3767
  items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
3582
3768
  ].join("\n\n");
3583
3769
  });
3584
- 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) => {
3585
3811
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3586
3812
  if (!profile) return "您暂未绑定句柄。";
3587
3813
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3588
3814
  const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3589
- if (existingEntries.length > 0) {
3590
- 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},无法重复购买`;
3591
3828
  }
3592
3829
  const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
3593
- if (!weapon) return "请输入“购买 物品名称”来购买所需物品。";
3594
- if (!weaponConfig[weapon]) return "无效的武器名称,请重新输入。";
3595
- const config2 = weaponConfig[weapon];
3596
- const allowedTypes = ["能量武器", "热能武器", "实弹武器"];
3597
- if (!allowedTypes.includes(config2.type)) {
3598
- return `❌ 无法购买该类型武器,仅支持:${allowedTypes.join("、")}`;
3599
- }
3600
- const existingWeapons = await ctx.database.get("ggcevo_equipment", {
3601
- handle,
3602
- weaponId: config2.id
3603
- });
3604
- if (existingWeapons.length > 0) {
3605
- 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
+ }
3606
3853
  }
3607
- const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
3854
+ const activeWish = isWeapon ? await ctx.database.get("ggcevo_Wish_Record", {
3608
3855
  handle,
3609
3856
  wishname: "蚱蜢优购",
3610
3857
  startTime: { $lte: /* @__PURE__ */ new Date() },
3611
3858
  endTime: { $gte: /* @__PURE__ */ new Date() },
3612
3859
  isused: false
3613
- }).then((records) => records[0]);
3614
- let actualPrice = config2.price;
3615
- let discountMessage = "";
3616
- let equippedCount;
3860
+ }).then((records) => records[0]) : null;
3617
3861
  if (activeWish) {
3618
- actualPrice = Math.floor(config2.price * 0.8);
3619
- 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);
3620
3870
  }
3621
3871
  if ((signInfo?.totalRewards || 0) < actualPrice) {
3622
- return `金币不足,需要${actualPrice}枚金币${discountMessage}`;
3872
+ let priceInfo = `需要 ${actualPrice} 金币`;
3873
+ if (discountDetails.length > 0) {
3874
+ priceInfo += `(原价 ${config2.price},累计折扣 ${totalDiscount}%)`;
3875
+ }
3876
+ return `❌ 金币不足,${priceInfo}`;
3623
3877
  }
3878
+ let isAutoEquipped = false;
3624
3879
  await ctx.database.withTransaction(async () => {
3625
3880
  await ctx.database.set("ggcevo_sign", { handle }, {
3626
3881
  totalRewards: signInfo.totalRewards - actualPrice
@@ -3630,32 +3885,55 @@ ${validTypes.join("、")}`;
3630
3885
  isused: true
3631
3886
  });
3632
3887
  }
3633
- await ctx.database.upsert("ggcevo_equipment", [{
3634
- handle,
3635
- weaponId: config2.id,
3636
- level: 0,
3637
- modificationSlots: 1,
3638
- equipped: false
3639
- }], ["handle", "weaponId"]);
3640
- equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
3641
- if (equippedCount === 0) {
3642
- await ctx.database.set(
3643
- "ggcevo_equipment",
3644
- { handle, weaponId: config2.id },
3645
- { equipped: true }
3646
- );
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"]);
3647
3915
  }
3648
3916
  });
3649
- let message = `成功购买 ${weapon}!花费 ${actualPrice}枚金币${discountMessage}。`;
3650
- if (activeWish) {
3651
- message += `
3652
- 🦗 蚱蜢优购祈愿已使用,下次购买将恢复原价。`;
3917
+ let message = `✅ 成功获取 ${isWeapon ? "武器" : "物品"}「${item}
3918
+ `;
3919
+ message += `花费 ${actualPrice} 金币`;
3920
+ if (discountDetails.length > 0) {
3921
+ message += `(原价 ${config2.price} 金币)
3922
+ 折扣明细:
3923
+ ▸ ${discountDetails.join("\n▸ ")}`;
3653
3924
  }
3654
- 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 });
3655
3932
  message += `
3656
- 已自动为您装备当前武器!`;
3933
+
3934
+ 当前持有数量:${current?.quantity || 1},输入「仓库」查看物品`;
3657
3935
  }
3658
- return message + "\n输入“武器仓库”查看你拥有的武器。";
3936
+ return message;
3659
3937
  });
3660
3938
  ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
3661
3939
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
@@ -3723,65 +4001,24 @@ ${validTypes.join("、")}`;
3723
4001
  });
3724
4002
  return `您已成功装备武器 ${weapon}!`;
3725
4003
  });
3726
- ctx.command("ggcevo/升级 <weapon>", "升级武器伤害").action(async ({ session }, weapon) => {
4004
+ ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
3727
4005
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3728
- if (!profile) return "您暂未绑定句柄。";
4006
+ if (!profile) return "❌ 您暂未绑定句柄";
3729
4007
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
3730
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
3731
- if (existingEntries.length > 0) {
3732
- return `❌ 拒绝访问,您已被列入黑名单。`;
3733
- }
3734
- const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
3735
- const [equipment] = await ctx.database.get("ggcevo_equipment", {
3736
- handle,
3737
- weaponId: weaponConfig[weapon]?.id
3738
- });
3739
- if (!weapon) return "请输入“升级 武器名称”来升级你想要的武器。";
3740
- if (!equipment) return "尚未获得该武器。";
3741
- if (equipment.level >= 6) return "该武器已达最大升级等级。";
3742
- const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
3743
- handle,
3744
- wishname: "灵狐升运",
3745
- startTime: { $lte: /* @__PURE__ */ new Date() },
3746
- endTime: { $gte: /* @__PURE__ */ new Date() },
3747
- isused: false
3748
- }).then((records) => records[0]);
3749
- let baseCost = [1050, 1450, 1850, 2250, 2650, 3050][equipment.level];
3750
- let actualCost = baseCost;
3751
- let discountMessage = "";
3752
- if (activeWish) {
3753
- actualCost = Math.floor(baseCost * 0.8);
3754
- discountMessage = ` (祈愿优惠价,原价${baseCost})`;
4008
+ if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
4009
+ return "❌ 拒绝访问,您已被列入黑名单";
3755
4010
  }
3756
- if ((signInfo?.totalRewards || 0) < actualCost)
3757
- return `需要${actualCost}枚金币${discountMessage},当前持有:${signInfo?.totalRewards || 0}。`;
3758
- await ctx.database.withTransaction(async () => {
3759
- await ctx.database.set("ggcevo_sign", { handle }, {
3760
- totalRewards: signInfo.totalRewards - actualCost
3761
- });
3762
- await ctx.database.set("ggcevo_equipment", {
3763
- handle,
3764
- weaponId: weaponConfig[weapon].id
3765
- }, {
3766
- level: equipment.level + 1,
3767
- modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
3768
- });
3769
- if (activeWish) {
3770
- await ctx.database.set("ggcevo_Wish_Record", { id: activeWish.id }, {
3771
- isused: true
3772
- });
3773
- }
3774
- });
3775
- const newLevel = equipment.level + 1;
3776
- const baseDamage = (weaponConfig[weapon].damage * (1 + 0.1 * newLevel)).toFixed(1);
3777
- const slots = Math.floor(newLevel / 3) + 1;
3778
- let message = `${weapon} 升级成功!花费${actualCost}枚金币${discountMessage}。`;
3779
- if (activeWish) {
3780
- message += `
3781
- 🦊 灵狐升运祈愿已使用,下次升级将恢复原价。`;
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);
3782
4020
  }
3783
- return `${message}
3784
- 当前等级:${newLevel},伤害:${baseDamage},拥有改装槽:${slots}个。`;
4021
+ return `❌ 未找到 "${target}" 对应的武器或科技`;
3785
4022
  });
3786
4023
  ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
3787
4024
  const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
@@ -4066,6 +4303,57 @@ ${effectMessage.join("\n")}`
4066
4303
  await ctx.broadcast(groupId, finalBroadcast);
4067
4304
  }
4068
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
+ });
4069
4357
  ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
4070
4358
  const pageNum = parseInt(page) || 1;
4071
4359
  if (pageNum < 1) return "请输入有效的页码。";
@@ -4151,7 +4439,7 @@ ${effectMessage.join("\n")}`
4151
4439
  name: minion.name,
4152
4440
  type: "子代",
4153
4441
  HP: minion.maxHP,
4154
- tags: bossConfig.main.tags,
4442
+ tags: minion.tags,
4155
4443
  skills: [...minion.passive],
4156
4444
  groupId: groupid,
4157
4445
  isActive: true,
@@ -4489,7 +4777,6 @@ ${effectMessage.join("\n")}`
4489
4777
  `🗓️ 就职时间:${formattedDate}`
4490
4778
  ];
4491
4779
  if (careerData.group === "辛迪加海盗") {
4492
- infoCard.push(`🔴 持有红晶:${careerData.redcrystal || 0} 个`);
4493
4780
  infoCard.push("💡 提示:红晶可通过主动PK获得(无论胜负)");
4494
4781
  } else {
4495
4782
  infoCard.push("💡 提示:使用「转职」命令可变更职业");
@@ -4505,11 +4792,18 @@ ${effectMessage.join("\n")}`
4505
4792
  }
4506
4793
  });
4507
4794
  ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
4795
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4796
+ if (!profile) return "⚠️ 需要先绑定游戏句柄";
4797
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4798
+ const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
4799
+ if (!careerData || careerData.group !== "辛迪加海盗") {
4800
+ return "🚫 该功能需要【辛迪加海盗】阵营权限";
4801
+ }
4508
4802
  const typeStats = {};
4509
- Object.values(weaponConfig).forEach((weapon) => {
4803
+ Object.values(weaponConfig).filter((config2) => config2.redCrystalCost > 0).forEach((weapon) => {
4510
4804
  typeStats[weapon.type] = (typeStats[weapon.type] || 0) + 1;
4511
4805
  });
4512
- Object.values(SyndicatedItems).forEach((item) => {
4806
+ Object.values(SyndicatedItems).filter((item) => item.redCrystalCost > 0).forEach((item) => {
4513
4807
  typeStats[item.type] = (typeStats[item.type] || 0) + 1;
4514
4808
  });
4515
4809
  if (!type) {
@@ -4524,12 +4818,15 @@ ${effectMessage.join("\n")}`
4524
4818
  const normalizedType = Object.keys(typeStats).find((t) => t === type);
4525
4819
  if (!normalizedType) return `无效类型,可用:${Object.keys(typeStats).join("、")}`;
4526
4820
  const items = [
4527
- ...Object.entries(weaponConfig).filter(([_, config2]) => config2.type === normalizedType).map(([name2, config2]) => {
4821
+ ...Object.entries(weaponConfig).filter(
4822
+ ([_, config2]) => config2.type === normalizedType && config2.redCrystalCost > 0
4823
+ ).map(([name2, config2]) => {
4528
4824
  const infoBlocks = [
4529
4825
  `【${name2}】`,
4530
4826
  `类型:${config2.type}`,
4531
4827
  ...config2.damage ? [`基础伤害:${config2.damage}`] : [],
4532
4828
  `订购价:${config2.redCrystalCost}红晶`
4829
+ // 只显示红晶价格
4533
4830
  ];
4534
4831
  if (Object.keys(config2.tagEffects).length > 0) {
4535
4832
  const tagEffectsDesc = Object.entries(config2.tagEffects).map(([tag, mul]) => `▸ 对${tag}目标造成${(mul * 100).toFixed(0)}%伤害`).join("\n");
@@ -4541,13 +4838,16 @@ ${effectMessage.join("\n")}`
4541
4838
  );
4542
4839
  return infoBlocks.join("\n");
4543
4840
  }),
4544
- ...Object.entries(SyndicatedItems).filter(([_, item]) => item.type === normalizedType).map(([name2, item]) => {
4841
+ ...Object.entries(SyndicatedItems).filter(
4842
+ ([_, item]) => item.type === normalizedType && item.redCrystalCost > 0
4843
+ ).map(([name2, item]) => {
4545
4844
  const infoBlocks = [
4546
4845
  `【${name2}】`,
4547
4846
  `类型:${item.type}`,
4548
4847
  `订购价:${item.redCrystalCost}红晶`,
4848
+ // 只显示红晶价格
4549
4849
  `效果:${item.effects}`,
4550
- item.description,
4850
+ `描述:${item.description}`,
4551
4851
  "──────────────"
4552
4852
  ];
4553
4853
  return infoBlocks.join("\n");
@@ -4688,7 +4988,7 @@ ${effectMessage.join("\n")}`
4688
4988
  }
4689
4989
  return message.join("\n");
4690
4990
  });
4691
- ctx.command("ggcevo/使用 [itemName]").action(async (argv, itemName) => {
4991
+ ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
4692
4992
  const session = argv.session;
4693
4993
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4694
4994
  if (!profile) return "🔒 需要先绑定游戏句柄";
@@ -4710,24 +5010,18 @@ ${effectMessage.join("\n")}`
4710
5010
  ([_, item]) => item.id === targetItem.itemId
4711
5011
  );
4712
5012
  const [itemNameConfirmed, itemConfig2] = itemEntry;
4713
- if (itemConfig2.id === 1) {
4714
- const activeSentry = await ctx.database.get("ggcevo_boss", {
4715
- name: "空间站哨枪塔",
4716
- isActive: true
4717
- });
4718
- if (!activeSentry.length) return "⚠️ 目标「空间站哨枪塔」未激活";
4719
- }
5013
+ const effectResult = await applyItemEffect(session, handle, itemConfig2, target);
5014
+ if (!effectResult.success) return effectResult.message;
4720
5015
  const newQuantity = targetItem.quantity - 1;
4721
5016
  await ctx.database.set(
4722
5017
  "ggcevo_warehouse",
4723
5018
  { handle, itemId: targetItem.itemId },
4724
5019
  { quantity: newQuantity }
4725
5020
  );
4726
- const effectResult = await applyItemEffect(session, handle, itemConfig2);
4727
5021
  return [
4728
5022
  `✅ 成功使用 ${itemNameConfirmed}`,
4729
5023
  `├ 剩余数量:${newQuantity}`,
4730
- `└ 效果触发:${effectResult}`,
5024
+ `└ 效果触发:${effectResult.message}`,
4731
5025
  "─".repeat(25)
4732
5026
  ].join("\n");
4733
5027
  } catch (error) {
@@ -4735,6 +5029,77 @@ ${effectMessage.join("\n")}`
4735
5029
  return "⚠️ 物品使用失败,请联系管理员";
4736
5030
  }
4737
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
+ });
4738
5103
  }
4739
5104
  __name(apply, "apply");
4740
5105
  function simpleDraw() {
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.2.72",
4
+ "version": "1.2.73",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [