koishi-plugin-ggcevo-game 1.3.36 → 1.3.38

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 +390 -150
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -444,13 +444,28 @@ function apply(ctx, config) {
444
444
  type: "能量武器",
445
445
  damage: 30,
446
446
  description: "激光步枪的变种,采用折射技术升级",
447
- specialeffect: "",
447
+ specialeffect: "攻击目标后,若有存活的其他异形,则对其造成20%的武器基础伤害",
448
448
  price: 1450,
449
449
  redCrystalCost: 15,
450
450
  isantiair: true,
451
451
  tagEffects: {
452
452
  "灵能": 1.5
453
453
  }
454
+ },
455
+ "粒子相位枪": {
456
+ id: 12,
457
+ type: "能量武器",
458
+ damage: 30,
459
+ description: "面对护盾目标而开发的武器",
460
+ specialeffect: "",
461
+ price: 1050,
462
+ redCrystalCost: 15,
463
+ isantiair: true,
464
+ tagEffects: {
465
+ "护盾": 2,
466
+ "轻甲": 0.5,
467
+ "重甲": 0.2
468
+ }
454
469
  }
455
470
  };
456
471
  const SyndicatedItems = {
@@ -477,6 +492,14 @@ function apply(ctx, config) {
477
492
  price: 0,
478
493
  redCrystalCost: 60,
479
494
  effects: "此物品存放于仓库,仅在处于辛迪加海盗阵营时生效。每日签到金币奖励+50%,每拥有100金币,增加1%(至多增加100%)"
495
+ },
496
+ "脉冲手雷": {
497
+ id: 4,
498
+ type: "手榴弹",
499
+ description: "电磁脉冲干扰机械目标和灵能目标",
500
+ price: 75,
501
+ redCrystalCost: 0,
502
+ effects: "对目标使用后,消耗其100点能量"
480
503
  }
481
504
  };
482
505
  const modConfig = {
@@ -673,7 +696,7 @@ function apply(ctx, config) {
673
696
  },
674
697
  "电能立场": {
675
698
  effect: 0,
676
- description: "当“能量”大于10%的时候,每次受到攻击有55%的概率消耗10%的“能量”免疫此次伤害(无法免疫寒冷伤害); 每拥有一层“寒冷”则降低5%的概率"
699
+ description: "当“能量”大于20%的时候,每次受到攻击有55%的概率免疫此次伤害(无法免疫寒冷伤害); 每拥有一层“寒冷”则降低5%的概率"
677
700
  },
678
701
  "电能冲击波": {
679
702
  effect: 0,
@@ -848,21 +871,21 @@ function apply(ctx, config) {
848
871
  const spaceStationCrewConfig = [
849
872
  {
850
873
  professionName: "深空矿工",
851
- effect: "每日签到获得的金币增加50%",
874
+ effect: "每日签到获得的金币+50%",
852
875
  requirements: "当月累计签到7天及以上",
853
876
  Jobtransfer: true,
854
877
  costcoins: 1500
855
878
  },
856
879
  {
857
880
  professionName: "警卫员下士",
858
- effect: "攻击获得的金币增加50%",
881
+ effect: "攻击获得的金币+50%",
859
882
  requirements: "当期伤害榜累计攻击4次及以上",
860
883
  Jobtransfer: true,
861
884
  costcoins: 2e3
862
885
  },
863
886
  {
864
887
  professionName: "警卫长",
865
- effect: "攻击伤害+5%,攻击获得的金币增加100%",
888
+ effect: "攻击伤害+5%,攻击获得的金币+100%",
866
889
  requirements: "当期伤害榜前十名",
867
890
  Jobtransfer: true,
868
891
  costcoins: 3e3
@@ -1113,6 +1136,45 @@ function apply(ctx, config) {
1113
1136
  careerBonus: "武器中士/情报副官: 武器改装通用模块享有20%的折扣; 武器改装专属模块享有10%的折扣"
1114
1137
  }
1115
1138
  ]
1139
+ },
1140
+ {
1141
+ techId: 4,
1142
+ techname: "安防系统",
1143
+ careerNames: ["警卫员下士", "警卫长", "情报副官"],
1144
+ // 新增职业名称字段
1145
+ maxLevel: 5,
1146
+ levels: [
1147
+ {
1148
+ level: 1,
1149
+ cost: 500,
1150
+ description: "重启安防参数代码,攻击获得的金币+5%",
1151
+ careerBonus: "警卫员下士/警卫长/情报副官: 攻击获得的金币+10%"
1152
+ },
1153
+ {
1154
+ level: 2,
1155
+ cost: 2050,
1156
+ description: "提高空间站安防系统强度,攻击获得的金币+10%",
1157
+ careerBonus: "警卫员下士/警卫长/情报副官: 攻击获得的金币+20%"
1158
+ },
1159
+ {
1160
+ level: 3,
1161
+ cost: 3250,
1162
+ description: "进一步提高空间站安防系统强度,攻击获得的金币+15%",
1163
+ careerBonus: "警卫员下士/警卫长/情报副官: 攻击获得的金币+30%"
1164
+ },
1165
+ {
1166
+ level: 4,
1167
+ cost: 4250,
1168
+ description: "大幅提高空间站安防系统强度,攻击获得的金币+20%",
1169
+ careerBonus: "警卫员下士/警卫长/情报副官: 攻击获得的金币+40%"
1170
+ },
1171
+ {
1172
+ level: 5,
1173
+ cost: 5350,
1174
+ description: "完全恢复空间站安防系统,攻击获得的金币+25%",
1175
+ careerBonus: "警卫员下士/警卫长/情报副官: 攻击获得的金币+50%; 打开安全军械库防爆门,随机获得一把传奇武器"
1176
+ }
1177
+ ]
1116
1178
  }
1117
1179
  ];
1118
1180
  const Tasklist = {
@@ -1449,6 +1511,7 @@ function apply(ctx, config) {
1449
1511
  tags: nextBossGroup.main.tags,
1450
1512
  // 新增标签字段
1451
1513
  skills: [...nextBossGroup.main.passive],
1514
+ energy: nextBossGroup.main.energy,
1452
1515
  groupId: nextBossGroup.main.id,
1453
1516
  isActive: true,
1454
1517
  respawnTime: /* @__PURE__ */ new Date()
@@ -1461,6 +1524,7 @@ function apply(ctx, config) {
1461
1524
  tags: minion.tags,
1462
1525
  // 新增标签字段
1463
1526
  skills: [...minion.passive],
1527
+ energy: minion.energy,
1464
1528
  groupId: mainBoss.groupId,
1465
1529
  isActive: true,
1466
1530
  respawnTime: /* @__PURE__ */ new Date()
@@ -1968,7 +2032,7 @@ function apply(ctx, config) {
1968
2032
  const currentFreezing = targetBoss.freezing || 0;
1969
2033
  let immuneChance = 55 - currentFreezing * 5;
1970
2034
  immuneChance = Math.max(immuneChance, 5);
1971
- if (currentEnergy < 100) {
2035
+ if (currentEnergy < 200) {
1972
2036
  return null;
1973
2037
  }
1974
2038
  const roll = Math.random() * 100;
@@ -1982,12 +2046,21 @@ function apply(ctx, config) {
1982
2046
  }
1983
2047
  return null;
1984
2048
  }, "handleEnergyField"),
2049
+ // 辅助函数:从配置中获取成员配置
2050
+ getMemberConfig: /* @__PURE__ */ __name((name2, bossGroup) => {
2051
+ if (bossGroup.main.name === name2) return bossGroup.main;
2052
+ for (const minion of bossGroup.minions) {
2053
+ if (minion.name === name2) return minion;
2054
+ }
2055
+ return null;
2056
+ }, "getMemberConfig"),
1985
2057
  // 处理脉冲效果(概率治疗全体异形)
1986
- handlePulse: /* @__PURE__ */ __name(async function(ctx2, targetBoss, activeBosses) {
2058
+ handlePulse: /* @__PURE__ */ __name(async function(ctx2, targetBoss, activeBosses, bossGroup) {
1987
2059
  if (!targetBoss.skills.includes("脉冲")) return null;
1988
2060
  const currentEnergy = targetBoss.energy || 0;
1989
2061
  const currentFreezing = targetBoss.freezing || 0;
1990
- if (currentEnergy < 80) {
2062
+ const maxEnergy = 1e3;
2063
+ if (currentEnergy < maxEnergy * 0.8) {
1991
2064
  return null;
1992
2065
  }
1993
2066
  let triggerChance = 60 - currentFreezing * 5;
@@ -1995,14 +2068,18 @@ function apply(ctx, config) {
1995
2068
  const roll = Math.random() * 100;
1996
2069
  if (roll <= triggerChance) {
1997
2070
  const groupMembers = activeBosses.filter(
1998
- (b) => b.groupId === targetBoss.groupId && b.HP > 0 && b.name !== targetBoss.name
1999
- // 不包括自己
2071
+ (b) => b.groupId === targetBoss.groupId && b.HP > 0
2072
+ // 只包括存活的异形
2000
2073
  );
2001
2074
  const updates = [];
2002
2075
  const healMessages = [];
2003
- groupMembers.forEach((member) => {
2004
- const healAmount = member.type === "主宰" ? 100 : 100;
2005
- const newHP = Math.min(member.HP + healAmount, member.maxHP);
2076
+ for (const member of groupMembers) {
2077
+ const memberConfig = this.getMemberConfig(member.name, bossGroup);
2078
+ if (!memberConfig) continue;
2079
+ const maxHP = memberConfig.maxHP;
2080
+ const healAmount = member.type === "主宰" ? 200 : 100;
2081
+ const newHP = Math.min(member.HP + healAmount, maxHP);
2082
+ const actualHeal = newHP - member.HP;
2006
2083
  updates.push(
2007
2084
  ctx2.database.set(
2008
2085
  "ggcevo_boss",
@@ -2010,13 +2087,17 @@ function apply(ctx, config) {
2010
2087
  { HP: newHP }
2011
2088
  )
2012
2089
  );
2013
- healMessages.push(`${member.name}+${healAmount}HP`);
2014
- });
2015
- if (groupMembers.length > 0) {
2090
+ if (actualHeal > 0) {
2091
+ healMessages.push(`${member.name}+${actualHeal}HP(当前${newHP}/${maxHP})`);
2092
+ } else {
2093
+ healMessages.push(`${member.name}生命值已满`);
2094
+ }
2095
+ }
2096
+ if (healMessages.length > 0) {
2016
2097
  await Promise.all(updates);
2017
2098
  return {
2018
2099
  messages: [
2019
- `❤️ 【脉冲】生效:治疗全体异形!(概率:${triggerChance.toFixed(1)}%)`,
2100
+ `❤️ 【脉冲】生效:治疗全体异形!`,
2020
2101
  ...healMessages
2021
2102
  ]
2022
2103
  };
@@ -2137,7 +2218,7 @@ function apply(ctx, config) {
2137
2218
  messages.push(...survivalResult.messages);
2138
2219
  skillUpdates.push(...survivalResult.skillUpdates);
2139
2220
  }
2140
- const pulseResult = await this.handlePulse(ctx2, targetBoss, activeBosses);
2221
+ const pulseResult = await this.handlePulse(ctx2, targetBoss, activeBosses, bossGroup);
2141
2222
  if (pulseResult) {
2142
2223
  messages.push(...pulseResult.messages);
2143
2224
  }
@@ -2353,6 +2434,134 @@ function apply(ctx, config) {
2353
2434
  return { rewardMessages };
2354
2435
  }
2355
2436
  __name(handleBossDefeatRewards, "handleBossDefeatRewards");
2437
+ async function handleSecondaryTargets(ctx2, session, equippedWeapon, targetBoss, weaponName, weaponData, activeBosses, bossGroup) {
2438
+ const scatterEffectMessages = [];
2439
+ const extraDamages = [];
2440
+ const actuallyDead = [];
2441
+ let scatterBroadcast = null;
2442
+ const secondaryTargets = activeBosses.filter(
2443
+ (boss) => boss.name !== targetBoss.name
2444
+ );
2445
+ if (secondaryTargets.length === 0) return {
2446
+ scatterEffectMessages,
2447
+ extraDamages,
2448
+ actuallyDead,
2449
+ scatterBroadcast
2450
+ };
2451
+ let scatterMsg = "";
2452
+ let scatterRatio = 0;
2453
+ if (weaponName === "碎骨步枪") {
2454
+ scatterMsg = "🔆 【光束曲射晶片】触发散射攻击!";
2455
+ scatterRatio = 0.5;
2456
+ } else if (weaponName === "中子步枪") {
2457
+ scatterMsg = "🔆 【中子步枪】触发散射攻击!";
2458
+ scatterRatio = 0.2;
2459
+ }
2460
+ scatterEffectMessages.push(scatterMsg);
2461
+ const baseDamage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
2462
+ const secondaryDamage = Math.round(baseDamage * scatterRatio);
2463
+ for (const secondaryTarget of secondaryTargets) {
2464
+ const secondaryMaxHP = getBossMaxHP(secondaryTarget.name);
2465
+ let currentDamage = secondaryDamage;
2466
+ const passiveResult = await PassiveHandler.handlePassives(
2467
+ ctx2,
2468
+ secondaryTarget,
2469
+ currentDamage,
2470
+ secondaryTarget.HP - currentDamage,
2471
+ secondaryMaxHP,
2472
+ weaponName,
2473
+ weaponData,
2474
+ secondaryTargets,
2475
+ // 传入所有次要目标作为上下文
2476
+ bossGroup
2477
+ );
2478
+ const finalDamage = passiveResult.initialDamage;
2479
+ const actualDamage = Math.min(finalDamage, secondaryTarget.HP);
2480
+ extraDamages.push({
2481
+ name: secondaryTarget.name,
2482
+ damage: actualDamage
2483
+ });
2484
+ const newHP = passiveResult.currentHP;
2485
+ if (passiveResult.skillUpdates.length > 0) {
2486
+ await PassiveHandler.applySkillUpdates(ctx2, passiveResult.skillUpdates);
2487
+ }
2488
+ const isDead = newHP <= 0;
2489
+ await ctx2.database.set(
2490
+ "ggcevo_boss",
2491
+ { name: secondaryTarget.name },
2492
+ {
2493
+ HP: Math.max(newHP, 0),
2494
+ isActive: !isDead
2495
+ }
2496
+ );
2497
+ scatterEffectMessages.push(
2498
+ ...passiveResult.messages.map((m) => ` 对 ${secondaryTarget.name} ${m}`)
2499
+ );
2500
+ if (isDead) {
2501
+ actuallyDead.push(secondaryTarget.name);
2502
+ if (secondaryTarget.type === "子代") {
2503
+ if (secondaryTarget.name === "机械感染虫") {
2504
+ const [mainBoss] = await ctx2.database.get("ggcevo_boss", {
2505
+ groupId: secondaryTarget.groupId,
2506
+ type: "主宰",
2507
+ isActive: true
2508
+ });
2509
+ if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
2510
+ await ctx2.database.set("ggcevo_boss", { name: mainBoss.name }, {
2511
+ skills: [...mainBoss.skills, "孤立无援"]
2512
+ });
2513
+ scatterBroadcast = "💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!";
2514
+ }
2515
+ } else {
2516
+ const remainingMinions = await ctx2.database.get("ggcevo_boss", {
2517
+ groupId: secondaryTarget.groupId,
2518
+ type: "子代",
2519
+ isActive: true
2520
+ });
2521
+ if (remainingMinions.length === 0) {
2522
+ const [mainBoss] = await ctx2.database.get("ggcevo_boss", {
2523
+ groupId: secondaryTarget.groupId,
2524
+ type: "主宰",
2525
+ isActive: true
2526
+ });
2527
+ if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
2528
+ await ctx2.database.set("ggcevo_boss", { name: mainBoss.name }, {
2529
+ skills: [...mainBoss.skills, "孤立无援"]
2530
+ });
2531
+ scatterBroadcast = `💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`;
2532
+ }
2533
+ }
2534
+ }
2535
+ } else if (secondaryTarget.type === "主宰") {
2536
+ await ctx2.database.set(
2537
+ "ggcevo_boss",
2538
+ { groupId: secondaryTarget.groupId },
2539
+ { isActive: false, HP: 0 }
2540
+ );
2541
+ const respawnTime = /* @__PURE__ */ new Date();
2542
+ respawnTime.setSeconds(respawnTime.getSeconds() + 3600);
2543
+ await ctx2.database.set(
2544
+ "ggcevo_boss",
2545
+ { name: secondaryTarget.name },
2546
+ { respawnTime }
2547
+ );
2548
+ const { rewardMessages } = await handleBossDefeatRewards(ctx2, secondaryTarget);
2549
+ await ctx2.database.remove("ggcevo_boss_damage", {
2550
+ bossGroupId: secondaryTarget.groupId
2551
+ });
2552
+ scatterBroadcast = [
2553
+ `🎯 主宰 ${secondaryTarget.name} 已被 ${session.username} 的散射伤害击败!`,
2554
+ `所有子代已消失,下一个主宰将在1小时后重生`,
2555
+ "",
2556
+ "🏆 伤害排行榜奖励:",
2557
+ ...rewardMessages
2558
+ ];
2559
+ }
2560
+ }
2561
+ }
2562
+ return { scatterEffectMessages, extraDamages, actuallyDead, scatterBroadcast };
2563
+ }
2564
+ __name(handleSecondaryTargets, "handleSecondaryTargets");
2356
2565
  async function checkTransferRequirements(ctx2, handle, profession) {
2357
2566
  const [mainBoss] = await ctx2.database.get("ggcevo_boss", {
2358
2567
  type: "主宰",
@@ -2504,7 +2713,7 @@ function apply(ctx, config) {
2504
2713
  });
2505
2714
  if (!targetboss.length || targetboss[0].Skillcountpoints === 0 || targetboss[0].tags.includes("建筑") || targetboss[0].tags.includes("重型")) return {
2506
2715
  success: false,
2507
- message: "您选择的不是合法目标(目标已死亡/目标的技能计数为0/目标拥有“建筑”或“重型”标签)"
2716
+ message: "您无法对目标使用。(目标已死亡/目标的技能计数为0/目标拥有“建筑”或“重型”标签)"
2508
2717
  };
2509
2718
  await ctx.database.set(
2510
2719
  "ggcevo_boss",
@@ -2522,9 +2731,32 @@ function apply(ctx, config) {
2522
2731
  message: `此物品无需使用,存放于仓库即刻生效。`
2523
2732
  };
2524
2733
  }
2734
+ if (itemConfig2.id === 4) {
2735
+ if (!target) return {
2736
+ success: false,
2737
+ message: "您未选择合适的目标。"
2738
+ };
2739
+ const targetboss = await ctx.database.get("ggcevo_boss", {
2740
+ name: target,
2741
+ isActive: true
2742
+ });
2743
+ if (!targetboss.length || targetboss[0].energy === 0) return {
2744
+ success: false,
2745
+ message: "您无法对目标使用。(目标的能量为0)"
2746
+ };
2747
+ await ctx.database.set(
2748
+ "ggcevo_boss",
2749
+ { name: target },
2750
+ { energy: targetboss[0].energy - 100 }
2751
+ );
2752
+ return {
2753
+ success: true,
2754
+ message: `成功使用 ${itemName},消耗 ${target} 100点能量`
2755
+ };
2756
+ }
2525
2757
  return {
2526
- success: true,
2527
- message: `${itemName} 效果已生效(开发中)`
2758
+ success: false,
2759
+ message: `${itemName} 效果开发中,无法使用`
2528
2760
  };
2529
2761
  } catch (error) {
2530
2762
  console.error("物品效果处理失败:", error);
@@ -3031,7 +3263,7 @@ ${itemDetails.join("\n")}`;
3031
3263
  ⚡ 加成效果:
3032
3264
  ▸ ${messages.join("\n▸ ")}`;
3033
3265
  }
3034
- return "签到成功!本月累计签到" + monthlyDays + "天,获得:\n💰 金币 x " + finalPoints + (totalBonus > 0 ? " (基础值 " + basePoints + ")" : "") + "\n🪙 咕咕币 x " + tickets + effectMessage;
3266
+ return "签到成功!本月累计签到" + monthlyDays + "天,获得:\n💰 金币 x " + finalPoints + (totalBonus > 0 ? " (基础值:" + basePoints + "金币)" : "") + "\n🪙 咕咕币 x " + tickets + effectMessage;
3035
3267
  } catch (error) {
3036
3268
  console.error("签到命令时发生错误:", error);
3037
3269
  return "服务器繁忙,请稍后尝试。";
@@ -4590,7 +4822,7 @@ ${validTypes.join("、")}`;
4590
4822
  }
4591
4823
  if (isWeapon) {
4592
4824
  if (isAutoEquipped) {
4593
- message += "\n【系统已自动装备该武器】";
4825
+ message += "\n【系统已为您自动装备该武器】";
4594
4826
  }
4595
4827
  message += "\n输入「武器仓库」查看详情";
4596
4828
  } else {
@@ -4801,9 +5033,50 @@ ${validTypes.join("、")}`;
4801
5033
  return showModList();
4802
5034
  }
4803
5035
  });
5036
+ ctx.command("ggcevo/拆卸 <weapon> <mod>", "卸载武器模块,专属模块返还50%金币,通用模块返还80%金币").action(async ({ session }, weapon, mod) => {
5037
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
5038
+ if (!profile) return "🔒 需要先绑定游戏句柄";
5039
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
5040
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
5041
+ if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
5042
+ const weaponId = weaponConfig[weapon]?.id;
5043
+ if (!weaponId) return "❌ 无效的武器名称";
5044
+ const modInfo = modConfig[mod];
5045
+ if (!modInfo) return "❌ 无效的模块名称";
5046
+ const refundRate = modInfo.isExclusive ? 0.5 : 0.8;
5047
+ const refundType = modInfo.isExclusive ? "专属模块返还50%" : "通用模块返还80%";
5048
+ const [equipment] = await ctx.database.get("ggcevo_equipment", {
5049
+ handle,
5050
+ weaponId
5051
+ });
5052
+ if (!equipment) return "❌ 您尚未获得该武器";
5053
+ if (!equipment.installedMods.includes(mod)) {
5054
+ return `❌ 该武器未安装${mod}模块`;
5055
+ }
5056
+ const refund = Math.floor(modInfo.cost * refundRate);
5057
+ const newMods = equipment.installedMods.filter((m) => m !== mod);
5058
+ await ctx.database.set(
5059
+ "ggcevo_equipment",
5060
+ { handle, weaponId },
5061
+ { installedMods: newMods }
5062
+ );
5063
+ const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
5064
+ const newBalance = (signInfo?.totalRewards || 0) + refund;
5065
+ await ctx.database.set("ggcevo_sign", { handle }, {
5066
+ totalRewards: newBalance
5067
+ });
5068
+ return [
5069
+ `✅ 已从 ${weapon} 拆卸 ${mod} 模块`,
5070
+ `返还金币:${refund} (原价${modInfo.cost},${refundType})`,
5071
+ `当前金币总额:${newBalance}`,
5072
+ `剩余模块:${newMods.join(", ") || "无"}`,
5073
+ modInfo.isExclusive ? "ℹ️ 专属模块拆卸只返还50%" : ""
5074
+ ].filter(Boolean).join("\n");
5075
+ });
4804
5076
  ctx.command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
4805
5077
  const session = argv.session;
4806
5078
  let broadcastMessage = null;
5079
+ let scatterBroadcast = null;
4807
5080
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4808
5081
  if (!profile) return "🔒 需要先绑定游戏句柄";
4809
5082
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -4857,118 +5130,29 @@ ${validTypes.join("、")}`;
4857
5130
  if (!bossGroup) return "无法获取异形组配置。";
4858
5131
  const maxHP = targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions.find((m) => m.name === targetBoss.name)?.maxHP || 0;
4859
5132
  const { damage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
4860
- const extraDamages = [];
4861
- const actuallyDead = [];
4862
- let scatterBroadcast = null;
4863
- if (equippedWeapon.installedMods?.includes("光束曲射晶片") && weaponName === "碎骨步枪") {
4864
- const activeBosses2 = await ctx.database.get("ggcevo_boss", {
4865
- isActive: true,
4866
- name: { $ne: targetBoss.name }
4867
- // 排除当前目标
4868
- });
4869
- if (activeBosses2.length > 0) {
4870
- effectMessage.push("🔆 【光束曲射晶片】触发!");
4871
- const baseDamage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
4872
- const secondaryDamage = Math.round(baseDamage * 0.5);
4873
- for (const secondaryTarget of activeBosses2) {
4874
- const secondaryMaxHP = getBossMaxHP(secondaryTarget.name);
4875
- let currentDamage = secondaryDamage;
4876
- const passiveResult2 = await PassiveHandler.handlePassives(
4877
- ctx,
4878
- secondaryTarget,
4879
- currentDamage,
4880
- secondaryTarget.HP - currentDamage,
4881
- secondaryMaxHP,
4882
- weaponName,
4883
- weaponData,
4884
- activeBosses2,
4885
- bossGroup
4886
- );
4887
- const finalDamage = passiveResult2.initialDamage;
4888
- const actualDamage = Math.min(finalDamage, secondaryTarget.HP);
4889
- extraDamages.push({
4890
- name: secondaryTarget.name,
4891
- damage: actualDamage
4892
- });
4893
- const newHP = passiveResult2.currentHP;
4894
- if (passiveResult2.skillUpdates.length > 0) {
4895
- await PassiveHandler.applySkillUpdates(ctx, passiveResult2.skillUpdates);
4896
- }
4897
- const isDead = newHP <= 0;
4898
- await ctx.database.set(
4899
- "ggcevo_boss",
4900
- { name: secondaryTarget.name },
4901
- {
4902
- HP: Math.max(newHP, 0),
4903
- isActive: !isDead
4904
- }
4905
- );
4906
- effectMessage.push(...passiveResult2.messages.map((m) => `+ 对 ${secondaryTarget.name} ${m}`));
4907
- if (isDead) {
4908
- actuallyDead.push(secondaryTarget.name);
4909
- if (secondaryTarget.type === "子代") {
4910
- if (secondaryTarget.name === "机械感染虫") {
4911
- const [mainBoss] = await ctx.database.get("ggcevo_boss", {
4912
- groupId: secondaryTarget.groupId,
4913
- type: "主宰",
4914
- isActive: true
4915
- });
4916
- if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
4917
- await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4918
- skills: [...mainBoss.skills, "孤立无援"]
4919
- });
4920
- broadcastMessage = "💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!";
4921
- }
4922
- } else {
4923
- const remainingMinions = await ctx.database.get("ggcevo_boss", {
4924
- groupId: secondaryTarget.groupId,
4925
- type: "子代",
4926
- isActive: true
4927
- });
4928
- if (remainingMinions.length === 0) {
4929
- const [mainBoss] = await ctx.database.get("ggcevo_boss", {
4930
- groupId: secondaryTarget.groupId,
4931
- type: "主宰",
4932
- isActive: true
4933
- });
4934
- if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
4935
- await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4936
- skills: [...mainBoss.skills, "孤立无援"]
4937
- });
4938
- broadcastMessage = `💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`;
4939
- }
4940
- }
4941
- }
4942
- } else if (secondaryTarget.type === "主宰") {
4943
- await ctx.database.set(
4944
- "ggcevo_boss",
4945
- { groupId: secondaryTarget.groupId },
4946
- {
4947
- isActive: false,
4948
- HP: 0
4949
- }
4950
- );
4951
- const respawnTime = /* @__PURE__ */ new Date();
4952
- respawnTime.setSeconds(respawnTime.getSeconds() + 3600);
4953
- await ctx.database.set(
4954
- "ggcevo_boss",
4955
- { name: secondaryTarget.name },
4956
- { respawnTime }
4957
- );
4958
- const { rewardMessages } = await handleBossDefeatRewards(ctx, secondaryTarget);
4959
- await ctx.database.remove("ggcevo_boss_damage", {
4960
- bossGroupId: secondaryTarget.groupId
4961
- });
4962
- scatterBroadcast = [
4963
- `🎯 主宰 ${secondaryTarget.name} 已被 ${session.username} 的散射伤害击败!`,
4964
- `所有子代已消失,下一个主宰将在1小时后重生`,
4965
- "",
4966
- "🏆 伤害排行榜奖励:",
4967
- ...rewardMessages
4968
- ].join("\n");
4969
- }
4970
- }
4971
- }
5133
+ let scatterEffectMessages = [];
5134
+ let extraDamages = [];
5135
+ let actuallyDead = [];
5136
+ if (equippedWeapon.installedMods?.includes("光束曲射晶片") && weaponName === "碎骨步枪" || weaponName === "中子步枪") {
5137
+ const activeBosses2 = await ctx.database.get("ggcevo_boss", { isActive: true });
5138
+ const bossGroup2 = bossPool.find(
5139
+ (g) => g.main.name === targetBoss.name || g.minions.some((m) => m.name === targetBoss.name)
5140
+ );
5141
+ if (bossGroup2) {
5142
+ const scatterResult = await handleSecondaryTargets(
5143
+ ctx,
5144
+ session,
5145
+ equippedWeapon,
5146
+ targetBoss,
5147
+ weaponName,
5148
+ weaponData,
5149
+ activeBosses2,
5150
+ bossGroup2
5151
+ );
5152
+ scatterEffectMessages = scatterResult.scatterEffectMessages;
5153
+ extraDamages = scatterResult.extraDamages;
5154
+ actuallyDead = scatterResult.actuallyDead;
5155
+ scatterBroadcast = scatterResult.scatterBroadcast;
4972
5156
  }
4973
5157
  }
4974
5158
  let initialDamage = Math.min(damage, targetBoss.HP);
@@ -5102,18 +5286,39 @@ ${validTypes.join("、")}`;
5102
5286
  }
5103
5287
  );
5104
5288
  }
5289
+ const SECURITY_BONUS_MAPPING = {
5290
+ // 普通用户加成 [等级1-5]
5291
+ base: [5, 10, 15, 20, 25],
5292
+ // 职业用户加成 [等级1-5]
5293
+ career: [10, 20, 30, 40, 50]
5294
+ };
5105
5295
  const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
5106
5296
  const career = careerData?.career;
5107
- let careerMultiplier = 1;
5297
+ const [securityTech] = await ctx.database.get("ggcevo_tech", {
5298
+ handle,
5299
+ techId: 4
5300
+ });
5301
+ let techBonusPercent = 0;
5302
+ if (securityTech && securityTech.level >= 1) {
5303
+ const techLevel = securityTech.level - 1;
5304
+ const securityConfig = Spacestationtechnology.find((t) => t.techId === 4);
5305
+ const isEligibleForCareerBonus = securityConfig?.careerNames.includes(career);
5306
+ techBonusPercent = isEligibleForCareerBonus ? SECURITY_BONUS_MAPPING.career[techLevel] : SECURITY_BONUS_MAPPING.base[techLevel];
5307
+ }
5308
+ const techMessage = techBonusPercent ? ` + ${techBonusPercent}% (${securityTech.level}级安防系统${career ? ` + ${career}职业加成` : ""})` : "";
5309
+ let careerMultiplier = 0;
5108
5310
  let careerMessage = "";
5109
5311
  let redcrystalMessage = "";
5110
5312
  if (career === "警卫员下士") {
5111
- careerMultiplier = 1.5;
5313
+ careerMultiplier = 50;
5112
5314
  careerMessage = "(+50% 警卫员下士职业加成)";
5113
5315
  } else if (career === "警卫长") {
5114
- careerMultiplier = 2;
5316
+ careerMultiplier = 100;
5115
5317
  careerMessage = "(+100% 警卫长职业加成)";
5116
5318
  }
5319
+ const totalBonusPercent = careerMultiplier + techBonusPercent;
5320
+ const totalBonusFactor = 1 + totalBonusPercent / 100;
5321
+ const finalReward = Math.round(totalDamage * totalBonusFactor);
5117
5322
  if (career === "清洁工") {
5118
5323
  await ctx.database.upsert("ggcevo_careers", [{
5119
5324
  handle,
@@ -5121,7 +5326,6 @@ ${validTypes.join("、")}`;
5121
5326
  }], ["handle"]);
5122
5327
  redcrystalMessage = "🔴 清洁工职业加成:获得1枚红晶";
5123
5328
  }
5124
- const finalReward = Math.round(totalDamage * careerMultiplier);
5125
5329
  const [existingSign] = await ctx.database.get("ggcevo_sign", { handle });
5126
5330
  await ctx.database.upsert("ggcevo_sign", [{
5127
5331
  handle,
@@ -5138,13 +5342,20 @@ ${effectMessage.map((m) => `▸ ${m}`).join("\n")}`
5138
5342
  ...passiveMessages.length > 0 ? [
5139
5343
  `🛡️ 被动效果:
5140
5344
  ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5345
+ ] : [],
5346
+ ...scatterEffectMessages.length > 0 ? [
5347
+ `⚡ 散射效果:
5348
+ ${scatterEffectMessages.map((m) => `▸ ${m}`).join("\n")}`
5141
5349
  ] : [],
5142
5350
  `造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
5143
5351
  ...extraDamages.length > 0 ? [
5144
5352
  `散射伤害:`,
5145
5353
  ...extraDamages.map((d) => `▸ 对 ${d.name} 造成 ${d.damage} 伤害`)
5146
5354
  ] : [],
5147
- `获得金币:${finalReward}${careerMessage}`,
5355
+ `获得金币:${finalReward}`,
5356
+ // === 新增详细金币加成信息 ===
5357
+ `${careerMultiplier > 0 ? `🛡️ 警卫职业加成: 金币+${careerMultiplier}%` : ""}`,
5358
+ `${techBonusPercent > 0 ? `🔧 安防系统加成: 金币+${techBonusPercent}%` : ""}`,
5148
5359
  redcrystalMessage,
5149
5360
  `目标剩余HP:${Math.max(currentHP, 0)}/${maxHP}`,
5150
5361
  ...actuallyDead.length > 0 ? [
@@ -5250,24 +5461,51 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5250
5461
  const mainBossHpBar = createHpBar(mainBoss.HP, bossGroup.main.maxHP);
5251
5462
  const result = [
5252
5463
  `🔴 主宰:${mainBoss.name}`,
5253
- `${mainBossHpBar} (${mainBoss.HP}/${bossGroup.main.maxHP})`,
5254
- `标签:${mainBoss.tags?.join("、") || "无"}`,
5255
- "被动:",
5256
- ...mainBoss.skills.map((p) => `${p}:${passiveConfig[p]?.description}`) || ["无"]
5464
+ `❤️ ${mainBossHpBar} (${mainBoss.HP}/${bossGroup.main.maxHP})`
5257
5465
  ];
5466
+ if (bossGroup.main.energy > 0) {
5467
+ result.push(`⚡ 能量:${mainBoss.energy}`);
5468
+ }
5469
+ result.push(
5470
+ `🏷️ 标签:${mainBoss.tags?.join("、") || "无"}`,
5471
+ `✨ 被动:`
5472
+ );
5473
+ if (mainBoss.skills.length > 0) {
5474
+ result.push(...mainBoss.skills.map((p) => `➤ ${p}:${passiveConfig[p]?.description}`));
5475
+ } else {
5476
+ result.push("➤ 无");
5477
+ }
5478
+ const countingSkill = mainBoss.skills?.find((s) => ["冷适应", "岗哨机枪", "吸血唾液"].includes(s));
5479
+ if (countingSkill) {
5480
+ result.push(`📈 ${countingSkill}:${mainBoss.Skillcountpoints}层`);
5481
+ }
5258
5482
  if (minions.length > 0) {
5259
5483
  result.push("\n🟠 子代:");
5260
5484
  for (let i = 0; i < minions.length; i++) {
5261
5485
  const minion = minions[i];
5262
5486
  const minionConfig = bossGroup.minions.find((m) => m.name === minion.name);
5263
5487
  const minionHpBar = createHpBar(minion.HP, minionConfig?.maxHP || 1e3);
5264
- result.push(
5265
- `${minion.name}`,
5266
- `${minionHpBar} (${minion.HP}/${minionConfig?.maxHP || "未知"})`,
5267
- `标签:${minion.tags?.join("、") || "无"}`,
5268
- "被动:",
5269
- ...minion.skills.map((p) => `${p}:${passiveConfig[p]?.description}`) || ["无"]
5488
+ const minionInfo = [
5489
+ `👤 ${minion.name}`,
5490
+ `❤️ ${minionHpBar} (${minion.HP}/${minionConfig?.maxHP || "未知"})`
5491
+ ];
5492
+ if (minionConfig && minionConfig.energy > 0) {
5493
+ minionInfo.push(`⚡ 能量:${minion.energy}`);
5494
+ }
5495
+ minionInfo.push(
5496
+ `🏷️ 标签:${minion.tags?.join("、") || "无"}`,
5497
+ `✨ 被动:`
5270
5498
  );
5499
+ if (minion.skills.length > 0) {
5500
+ minionInfo.push(...minion.skills.map((p) => `➤ ${p}:${passiveConfig[p]?.description}`));
5501
+ } else {
5502
+ minionInfo.push("➤ 无");
5503
+ }
5504
+ const minionCountingSkill = minion.skills?.find((s) => ["冷适应", "岗哨机枪", "吸血唾液"].includes(s));
5505
+ if (minionCountingSkill) {
5506
+ minionInfo.push(`📈 ${minionCountingSkill}:${minion.Skillcountpoints}层`);
5507
+ }
5508
+ result.push(...minionInfo);
5271
5509
  if (i < minions.length - 1) result.push("");
5272
5510
  }
5273
5511
  }
@@ -5286,6 +5524,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5286
5524
  HP: bossConfig.main.maxHP,
5287
5525
  tags: bossConfig.main.tags,
5288
5526
  skills: [...bossConfig.main.passive],
5527
+ energy: bossConfig.main.energy,
5289
5528
  groupId: groupid,
5290
5529
  isActive: true,
5291
5530
  respawnTime: /* @__PURE__ */ new Date()
@@ -5297,6 +5536,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
5297
5536
  HP: minion.maxHP,
5298
5537
  tags: minion.tags,
5299
5538
  skills: [...minion.passive],
5539
+ energy: minion.energy,
5300
5540
  groupId: groupid,
5301
5541
  isActive: true,
5302
5542
  respawnTime: /* @__PURE__ */ new Date()
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.36",
4
+ "version": "1.3.38",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [