koishi-plugin-ggcevo-game 1.3.16 → 1.3.18

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 +379 -329
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -516,19 +516,19 @@ function apply(ctx, config) {
516
516
  rare: [
517
517
  {
518
518
  name: "悲鸣之锋",
519
- effect: "增加基于武器等级的伤害加成(0级为10%,每等级增加10%)"
519
+ effect: "获得基于武器等级的伤害加成(0级为10%,每等级增加10%)"
520
520
  },
521
521
  {
522
522
  name: "精灵双倍",
523
- effect: "下一次击败首领时可获得双倍奖励"
523
+ effect: "下一次击败首领时可获得双倍金币和咕咕币奖励"
524
524
  },
525
525
  {
526
526
  name: "喵喵财源",
527
- effect: "签到奖励翻倍"
527
+ effect: "签到金币和咕咕币奖励翻倍"
528
528
  },
529
529
  {
530
530
  name: "暴击韵律",
531
- effect: "攻击时,暴击率+20%"
531
+ effect: "攻击暴击率+20%"
532
532
  },
533
533
  {
534
534
  name: "酥手空空",
@@ -585,7 +585,7 @@ function apply(ctx, config) {
585
585
  },
586
586
  "冷适应": {
587
587
  effect: 0,
588
- description: "受到10次寒冷伤害后,永久获得“惧热”标签,同时免疫寒冷伤害"
588
+ description: "受到10次寒冷伤害后,自身获得“惧热”标签,并且免疫寒冷伤害"
589
589
  },
590
590
  "感染空间站": {
591
591
  effect: 0,
@@ -597,11 +597,11 @@ function apply(ctx, config) {
597
597
  },
598
598
  "霉菌滋生": {
599
599
  effect: 0,
600
- description: "自身每受到1次攻击,若“空间站哨枪塔”存活,则为其回复1%的最大生命值"
600
+ description: "受到攻击后,若“空间站哨枪塔”存活,则为其回复1%的最大生命值"
601
601
  },
602
602
  "岗哨机枪": {
603
603
  effect: 0,
604
- description: "自己的职责为“保护感染虫”,受到10次攻击后,为存活的机械感染虫和主宰回复10%的最大生命值(可重复触发)"
604
+ description: "受到10次攻击后,为存活的异形回复其10%的最大生命值(可重复触发)"
605
605
  },
606
606
  "结构装甲": {
607
607
  effect: 0,
@@ -609,15 +609,15 @@ function apply(ctx, config) {
609
609
  },
610
610
  "吸血唾液": {
611
611
  effect: 0,
612
- description: "受到攻击将会获得一层“吸血”,每层“吸血”提供5%的减伤,至多10层"
612
+ description: "受到攻击将会获得一层“吸血”,每层“吸血”提供5%的减伤(至多10层)"
613
613
  },
614
614
  "进食": {
615
615
  effect: 0,
616
- description: "当“吸血”层数达到10层后,下一次受到攻击,将会消耗所有层数回复自身20%的最大生命值"
616
+ description: "当“吸血”达到10层后,下一次受到攻击将会消耗所有层数回复自身20%的最大生命值"
617
617
  },
618
618
  "嗜血狂暴": {
619
619
  effect: 0,
620
- description: "血量低于50%时,每次受到攻击将会额外叠加一层吸血唾液,并且受到的伤害-20%"
620
+ description: "血量低于50%时,每次受到攻击将会额外活到一层“吸血”,并且受到的伤害-20%"
621
621
  },
622
622
  "吐血": {
623
623
  effect: 0,
@@ -1010,34 +1010,56 @@ function apply(ctx, config) {
1010
1010
  ]
1011
1011
  }
1012
1012
  ];
1013
- function calculateModifiers(equippedWeapon, weaponName, hasCritRhythm) {
1014
- let totalModAdd = 0;
1015
- let hasCrit = false;
1016
- let hasCrystal = false;
1017
- let hasOverload = false;
1018
- equippedWeapon.installedMods.forEach((mod) => {
1019
- if (mod === "动能增幅") {
1020
- totalModAdd += 0.2;
1021
- }
1022
- if (mod === "裂甲核心" && weaponName === modConfig[mod].exclusiveTo) {
1023
- totalModAdd += 0.4;
1024
- }
1025
- if (mod === "棱镜水晶") hasCrystal = true;
1026
- if (mod === "棱镜超载核心" && weaponName === modConfig[mod].exclusiveTo) {
1027
- hasOverload = true;
1028
- }
1029
- });
1030
- let totalCritRate = (hasCrystal ? 20 : 0) + (hasOverload ? 80 : 0);
1031
- if (hasCritRhythm) {
1032
- totalCritRate = Math.min(totalCritRate + 20, 100);
1033
- }
1034
- if (totalCritRate > 0 && Math.random() < totalCritRate / 100) {
1035
- hasCrit = true;
1036
- totalModAdd += 1;
1013
+ async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss, options) {
1014
+ let effectMessage = [];
1015
+ const finalTags = options?.customTags || targetBoss.tags || [];
1016
+ const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
1017
+ const { regionId, realmId, profileId } = profile;
1018
+ const handle = `${regionId}-S2-${realmId}-${profileId}`;
1019
+ const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
1020
+ const [weaponName, weaponData] = weaponConfigEntry;
1021
+ const baseDamage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
1022
+ let totalAdditive = 0;
1023
+ const tagAdditive = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
1024
+ totalAdditive += tagAdditive;
1025
+ const { totalModAdd, hasCrit } = calculateModifiers(
1026
+ equippedWeapon,
1027
+ weaponName,
1028
+ await checkCritRhythm(ctx2, handle)
1029
+ );
1030
+ totalAdditive += totalModAdd;
1031
+ if (hasCrit) effectMessage.push("✨ 触发暴击!");
1032
+ const careerBonus = await calculateCareerAdditive(ctx2, handle, weaponData.type, weaponData.id);
1033
+ totalAdditive += careerBonus.value;
1034
+ if (careerBonus.message) effectMessage.push(careerBonus.message);
1035
+ const wishAdditive = await calculateWishAdditive(ctx2, handle, equippedWeapon);
1036
+ totalAdditive += wishAdditive.value;
1037
+ if (wishAdditive.message) effectMessage.push(wishAdditive.message);
1038
+ const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle, rankseason: config.rankseason });
1039
+ totalAdditive += calculateRankAdditive(rankRecord);
1040
+ let finalDamage = baseDamage * (1 + totalAdditive);
1041
+ const minDamage = baseDamage * 0.01;
1042
+ if (finalDamage < minDamage) {
1043
+ finalDamage = minDamage;
1044
+ effectMessage.push("⚠️ 触发保底机制:造成基础伤害的1%");
1037
1045
  }
1038
- return { totalModAdd, hasCrit };
1046
+ return {
1047
+ damage: Math.round(finalDamage),
1048
+ hasCrit,
1049
+ effectMessage
1050
+ };
1039
1051
  }
1040
- __name(calculateModifiers, "calculateModifiers");
1052
+ __name(calculateTotalDamage, "calculateTotalDamage");
1053
+ async function checkCritRhythm(ctx2, handle) {
1054
+ const [record] = await ctx2.database.get("ggcevo_Wish_Record", {
1055
+ handle,
1056
+ wishname: "暴击韵律",
1057
+ startTime: { $lte: /* @__PURE__ */ new Date() },
1058
+ endTime: { $gte: /* @__PURE__ */ new Date() }
1059
+ });
1060
+ return !!record;
1061
+ }
1062
+ __name(checkCritRhythm, "checkCritRhythm");
1041
1063
  async function calculateTagMultiplier(weaponData, tags, equippedWeapon) {
1042
1064
  const MOD_EFFECTS = [
1043
1065
  { mod: "裂甲核心", tag: "重甲", value: 1.2 },
@@ -1054,135 +1076,118 @@ function apply(ctx, config) {
1054
1076
  return totalAdditive;
1055
1077
  }
1056
1078
  __name(calculateTagMultiplier, "calculateTagMultiplier");
1057
- function calculatePassiveEffects(passives) {
1058
- let passiveEffect = 0;
1059
- passives.forEach((passive) => {
1060
- const effect = passiveConfig[passive]?.effect || 0;
1061
- passiveEffect += effect;
1079
+ function calculateModifiers(equippedWeapon, weaponName, hasCritRhythm) {
1080
+ let totalModAdd = 0;
1081
+ let hasCrit = false;
1082
+ let crystalCrit = 0;
1083
+ let overloadCrit = 0;
1084
+ let rhythmCrit = 0;
1085
+ equippedWeapon.installedMods.forEach((mod) => {
1086
+ if (mod === "动能增幅") {
1087
+ totalModAdd += 0.2;
1088
+ }
1089
+ if (mod === "裂甲核心" && weaponName === modConfig[mod].exclusiveTo) {
1090
+ totalModAdd += 0.4;
1091
+ }
1092
+ if (mod === "棱镜水晶") {
1093
+ crystalCrit = 20;
1094
+ }
1095
+ if (mod === "棱镜超载核心" && weaponName === modConfig[mod].exclusiveTo) {
1096
+ overloadCrit = 80;
1097
+ }
1062
1098
  });
1063
- return passiveEffect;
1099
+ rhythmCrit = hasCritRhythm ? 20 : 0;
1100
+ const totalCritRate = Math.min(
1101
+ crystalCrit + overloadCrit + rhythmCrit,
1102
+ 100
1103
+ );
1104
+ if (totalCritRate > 0) {
1105
+ const roll = Math.random() * 100;
1106
+ if (roll <= totalCritRate) {
1107
+ hasCrit = true;
1108
+ totalModAdd += 1;
1109
+ }
1110
+ }
1111
+ return { totalModAdd, hasCrit };
1064
1112
  }
1065
- __name(calculatePassiveEffects, "calculatePassiveEffects");
1066
- async function calculateCareerBonus(ctx2, handle, currentDamage, weaponType, weaponId) {
1113
+ __name(calculateModifiers, "calculateModifiers");
1114
+ async function calculateCareerAdditive(ctx2, handle, weaponType, weaponId) {
1067
1115
  const [careerData] = await ctx2.database.get("ggcevo_careers", { handle });
1068
- const career = careerData?.career;
1069
- const faction = careerData?.group;
1116
+ let value = 0;
1070
1117
  let message = "";
1071
- let multiplier = 1;
1072
- if (career === "警卫长") {
1073
- multiplier = 1.05;
1118
+ if (careerData?.career === "警卫长") {
1119
+ value += 0.05;
1074
1120
  message = "⚔️ 职业加成:警卫长(攻击伤害+5%)";
1075
- } else if (career === "武器中士") {
1076
- multiplier = 1.15;
1121
+ }
1122
+ if (careerData?.career === "武器中士") {
1123
+ value += 0.15;
1077
1124
  message = "⚔️ 职业加成:武器中士(攻击伤害+15%)";
1078
1125
  }
1079
- if (faction === "辛迪加海盗" && career === "能量武器专家") {
1126
+ if (careerData?.career === "能量武器专家") {
1080
1127
  if (weaponType === "能量武器") {
1081
- multiplier *= 1.2;
1082
- message = " 职业加成:能量武器专家(能量武器伤害+20%)";
1083
- } else {
1084
- message = "⚠️ 能量武器专家:未装备能量武器,加成未生效";
1128
+ value += 0.2;
1129
+ message = "⚔️ 职业加成:能量武器专家(能量武器伤害+20%)";
1085
1130
  }
1086
1131
  }
1087
- if (faction === "辛迪加海盗" && career === "纵火狂") {
1132
+ if (careerData?.career === "纵火狂") {
1088
1133
  if (weaponType === "热能武器") {
1089
- multiplier *= 1.2;
1090
- message = " 职业加成:纵火狂(热能武器伤害+20%)";
1091
- } else {
1092
- message = "⚠️ 纵火狂:未装备热能武器,加成未生效";
1134
+ value += 0.2;
1135
+ message = "⚔️ 职业加成:纵火狂(热能武器伤害+20%)";
1093
1136
  }
1094
1137
  }
1095
- if (faction === "辛迪加海盗" && career === "猩红杀手") {
1138
+ if (careerData?.career === "猩红杀手") {
1096
1139
  if (weaponId === 7) {
1097
- multiplier *= 1.15;
1098
- message = " 职业加成:猩红杀手(侦查步枪伤害+15%)";
1099
- } else {
1100
- message = "⚠️ 猩红杀手:未装备侦查步枪,加成未生效";
1140
+ value += 0.15;
1141
+ message = "⚔️ 职业加成:猩红杀手(侦查步枪伤害+15%)";
1101
1142
  }
1102
1143
  }
1103
- return {
1104
- damage: currentDamage * multiplier,
1105
- message: message || void 0
1106
- };
1107
- }
1108
- __name(calculateCareerBonus, "calculateCareerBonus");
1109
- function calculateRankBonus(rankRecord) {
1110
- if (!rankRecord || rankRecord.rank <= 0) return 0;
1111
- return Math.floor(rankRecord.rank / 400) * 0.01;
1144
+ return { value, message };
1112
1145
  }
1113
- __name(calculateRankBonus, "calculateRankBonus");
1114
- async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss, options) {
1115
- let effectMessage = [];
1116
- const finalTags = options?.customTags || targetBoss.tags || [];
1117
- const finalPassives = options?.customPassives || targetBoss.skills || [];
1118
- const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
1119
- const { regionId, realmId, profileId } = profile;
1120
- const handle = `${regionId}-S2-${realmId}-${profileId}`;
1121
- const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
1122
- const [weaponName, weaponData] = weaponConfigEntry;
1123
- const weaponType = weaponData.type;
1124
- const weaponId = weaponData.id;
1125
- let damage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
1126
- const [critRhythmEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
1146
+ __name(calculateCareerAdditive, "calculateCareerAdditive");
1147
+ async function calculateWishAdditive(ctx2, handle, weapon) {
1148
+ let value = 0;
1149
+ const messages = [];
1150
+ const [sovereign] = await ctx2.database.get("ggcevo_Wish_Record", {
1127
1151
  handle,
1128
- wishname: "暴击韵律",
1152
+ wishname: "王权增幅",
1129
1153
  startTime: { $lte: /* @__PURE__ */ new Date() },
1130
1154
  endTime: { $gte: /* @__PURE__ */ new Date() }
1131
1155
  });
1132
- const { totalModAdd, hasCrit } = calculateModifiers(
1133
- equippedWeapon,
1134
- weaponName,
1135
- !!critRhythmEffect
1136
- );
1137
- damage *= 1 + totalModAdd;
1138
- if (critRhythmEffect) {
1139
- effectMessage.push("🎵 暴击韵律祈愿生效(武器暴击率+20%)");
1140
- }
1141
- const tagMultiplier = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
1142
- damage *= 1 + tagMultiplier;
1143
- const passiveMultiplier = calculatePassiveEffects(finalPassives);
1144
- damage *= 1 + passiveMultiplier;
1145
- const { damage: careerDamage, message: careerMessage } = await calculateCareerBonus(
1146
- ctx2,
1147
- handle,
1148
- damage,
1149
- weaponType,
1150
- // 新增参数
1151
- weaponId
1152
- );
1153
- damage = careerDamage;
1154
- if (careerMessage) effectMessage.push(careerMessage);
1155
- const [sovereignEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
1156
+ if (sovereign) {
1157
+ value += 0.05;
1158
+ messages.push("👑 王权增幅(攻击伤害+5%)");
1159
+ }
1160
+ const [lament] = await ctx2.database.get("ggcevo_Wish_Record", {
1156
1161
  handle,
1157
- wishname: "王权增幅",
1162
+ wishname: "悲鸣之锋",
1158
1163
  startTime: { $lte: /* @__PURE__ */ new Date() },
1159
1164
  endTime: { $gte: /* @__PURE__ */ new Date() }
1160
1165
  });
1161
- const [lamentEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
1166
+ if (lament) {
1167
+ const levelBonus = 0.1 * (weapon.level + 1);
1168
+ value += levelBonus;
1169
+ messages.push(`🗡️ 悲鸣之锋(攻击伤害+${Math.round(levelBonus * 100)}%)`);
1170
+ }
1171
+ const [critRhythm] = await ctx2.database.get("ggcevo_Wish_Record", {
1162
1172
  handle,
1163
- wishname: "悲鸣之锋",
1173
+ wishname: "暴击韵律",
1164
1174
  startTime: { $lte: /* @__PURE__ */ new Date() },
1165
1175
  endTime: { $gte: /* @__PURE__ */ new Date() }
1166
1176
  });
1167
- if (sovereignEffect) {
1168
- damage *= 1.05;
1169
- effectMessage.push(`👑 王权增幅祈愿生效(攻击伤害+5%)`);
1170
- }
1171
- if (lamentEffect) {
1172
- const levelBonus = 0.1 * (equippedWeapon.level + 1);
1173
- damage *= 1 + levelBonus;
1174
- effectMessage.push(`🗡️ 悲鸣之锋祈愿生效(基于武器等级,攻击伤害+${(levelBonus * 100).toFixed(0)}%)`);
1175
- }
1176
- const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle: session.handle, rankseason: config.rankseason });
1177
- const rankBonus = calculateRankBonus(rankRecord);
1178
- damage *= 1 + rankBonus;
1177
+ if (critRhythm) {
1178
+ messages.push("🎵 暴击韵律(攻击暴击率+20%)");
1179
+ }
1179
1180
  return {
1180
- damage: Math.round(damage),
1181
- hasCrit,
1182
- effectMessage
1181
+ value,
1182
+ message: messages.join(",")
1183
1183
  };
1184
1184
  }
1185
- __name(calculateTotalDamage, "calculateTotalDamage");
1185
+ __name(calculateWishAdditive, "calculateWishAdditive");
1186
+ function calculateRankAdditive(rankRecord) {
1187
+ if (!rankRecord || rankRecord.rank <= 0) return 0;
1188
+ return Math.floor(rankRecord.rank / 400) * 0.01;
1189
+ }
1190
+ __name(calculateRankAdditive, "calculateRankAdditive");
1186
1191
  const initDefaultItems = {
1187
1192
  "咕咕币": { id: 1, type: "抽奖道具", description: "用于进行抽奖" },
1188
1193
  "兑换券": { id: 2, type: "兑换货币", description: "用于兑换赞助物品" },
@@ -1361,20 +1366,21 @@ function apply(ctx, config) {
1361
1366
  }, 60 * 1e3);
1362
1367
  const PassiveHandler = {
1363
1368
  // 冰霜进化处理(免疫冰霜伤害)
1364
- handleFrostEvolution: /* @__PURE__ */ __name(function(targetBoss, weaponName, baseDamage, currentHP, maxHP) {
1369
+ handleFrostEvolution: /* @__PURE__ */ __name(function(targetBoss, weaponName, damage, maxHP) {
1365
1370
  if (targetBoss.skills.includes("冰霜进化") && weaponName === "零度之下") {
1366
- const healAmount = baseDamage;
1371
+ const healAmount = damage;
1367
1372
  return {
1368
1373
  updatedHP: Math.min(targetBoss.HP + healAmount, maxHP),
1369
1374
  initialDamage: 0,
1370
- messages: [`❄️ ${targetBoss.name} 触发【冰霜进化】免疫冰霜伤害!并且回复 ${healAmount} 生命值`]
1375
+ // 直接设置伤害为0
1376
+ messages: [`❄️ 【冰霜进化】生效:免疫冰霜伤害,${targetBoss.name}回复 ${healAmount} 生命值`]
1371
1377
  };
1372
1378
  }
1373
1379
  return null;
1374
1380
  }, "handleFrostEvolution"),
1375
1381
  // 冰霜环绕处理(主宰专用)
1376
- handleFrostSurround: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP, bossGroup) => {
1377
- if (targetBoss.type !== "主宰" || !targetBoss.skills.includes("冰霜环绕") || currentHP <= 0 || // 新增血量必须大于0的判断
1382
+ handleFrostSurround: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP) => {
1383
+ if (!targetBoss.skills.includes("冰霜环绕") || currentHP <= 0 || // 新增血量必须大于0的判断
1378
1384
  currentHP / maxHP > 0.3) {
1379
1385
  return null;
1380
1386
  }
@@ -1400,14 +1406,14 @@ function apply(ctx, config) {
1400
1406
  updatedHP,
1401
1407
  skillUpdates,
1402
1408
  messages: [
1403
- `❄️ ${targetBoss.name} 触发【冰霜环绕】,自身回复45%最大生命值(+${healAmount}HP)`,
1404
- `🌪️ 【寒霜地狱】降临!主宰和所有存活的子代将获得30%减伤效果`
1409
+ `❄️ 【冰霜环绕】生效,${targetBoss.name}回复45%最大生命值(+${healAmount}HP)`,
1410
+ `🌪️ 警告!【寒霜地狱】降临,所有存活的异形获得30%减伤效果`
1405
1411
  ]
1406
1412
  };
1407
1413
  }, "handleFrostSurround"),
1408
1414
  // 冰霜回复处理(子代专用)
1409
1415
  handleFrostRecovery: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP, activeBosses, bossGroup) => {
1410
- if (targetBoss.type !== "子代" || !targetBoss.skills.includes("冰霜回复") || currentHP <= 0 || // 新增血量必须大于0的判断
1416
+ if (!targetBoss.skills.includes("冰霜回复") || currentHP <= 0 || // 新增血量必须大于0的判断
1411
1417
  currentHP / maxHP > 0.3) {
1412
1418
  return null;
1413
1419
  }
@@ -1433,7 +1439,7 @@ function apply(ctx, config) {
1433
1439
  remove: ["冰霜回复"]
1434
1440
  }],
1435
1441
  messages: [
1436
- `❄️ ${targetBoss.name} 触发【冰霜回复】,自身回复40%最大生命值(+${selfHeal}HP),主宰回复10%最大生命值(+${mainHeal}HP)`
1442
+ `❄️ 【冰霜回复】生效,${targetBoss.name}回复40%最大生命值(+${selfHeal}HP),${mainBoss.name}回复10%最大生命值(+${mainHeal}HP)`
1437
1443
  ]
1438
1444
  };
1439
1445
  }, "handleFrostRecovery"),
@@ -1452,24 +1458,25 @@ function apply(ctx, config) {
1452
1458
  tags: newtags
1453
1459
  });
1454
1460
  return {
1455
- messages: [`❄️ ${targetBoss.name} 触发【冷适应】,永久获得「惧热」标签并免疫寒冷伤害!`]
1461
+ messages: [`❄️ 【冷适应】生效,${targetBoss.name}获得「惧热」标签`]
1456
1462
  };
1457
1463
  }
1458
1464
  return null;
1459
1465
  }, "handleColdAdaptation"),
1460
- // 新增冷适应免疫处理函数(模仿冰霜进化)
1466
+ // 冷适应免疫处理
1461
1467
  handleColdAdaptationImmunity: /* @__PURE__ */ __name(function(targetBoss, weaponName) {
1462
- if (targetBoss.type === "主宰" && targetBoss.name === "莽兽" && targetBoss.skills.includes("冷适应") && targetBoss.Skillcountpoints >= 10 && weaponName === "零度之下") {
1468
+ if (targetBoss.skills.includes("冷适应") && targetBoss.Skillcountpoints >= 10 && weaponName === "零度之下") {
1463
1469
  return {
1464
1470
  initialDamage: 0,
1465
- messages: [`❄️ ${targetBoss.name} 触发【冷适应】免疫寒冷伤害!`]
1471
+ // 直接设置伤害为0
1472
+ messages: [`❄️ 【冷适应】生效:免疫寒冷伤害`]
1466
1473
  };
1467
1474
  }
1468
1475
  return null;
1469
1476
  }, "handleColdAdaptationImmunity"),
1470
1477
  // 求生本能处理
1471
1478
  handleSurvivalInstinct: /* @__PURE__ */ __name(function(targetBoss, currentHP, maxHP) {
1472
- if (currentHP > 1) return null;
1479
+ if (currentHP > 0) return null;
1473
1480
  let effect = null;
1474
1481
  if (targetBoss.skills.includes("求生本能I")) {
1475
1482
  effect = { heal: maxHP * 0.3, skill: "求生本能I" };
@@ -1479,28 +1486,21 @@ function apply(ctx, config) {
1479
1486
  if (!effect) return null;
1480
1487
  return {
1481
1488
  updatedHP: effect.heal,
1482
- messages: [`${targetBoss.name} 触发【${effect.skill}】,瞬间回复${effect.heal}生命值!`],
1489
+ messages: [`【${effect.skill}】生效,${targetBoss.name}瞬间回复${effect.heal}生命值!`],
1483
1490
  skillUpdates: [{
1484
1491
  name: targetBoss.name,
1485
1492
  remove: [effect.skill]
1486
1493
  }]
1487
1494
  };
1488
1495
  }, "handleSurvivalInstinct"),
1489
- // 感染空间站处理
1490
- handleInfectedStation: /* @__PURE__ */ __name(async (ctx2, targetBoss, initialDamage, bossGroup) => {
1491
- if (targetBoss.name !== "空间站感染虫" || !targetBoss.skills.includes("感染空间站")) {
1492
- return null;
1493
- }
1494
- const sentryConfig = bossGroup.minions.find((m) => m.name === "空间站哨枪塔");
1495
- if (!sentryConfig) return null;
1496
- const [sentryGun] = await ctx2.database.get("ggcevo_boss", {
1497
- name: "空间站哨枪塔",
1498
- isActive: true
1499
- });
1496
+ // 感染空间站处理(返回减伤系数)
1497
+ handleInfectedStation: /* @__PURE__ */ __name(async (ctx2, targetBoss) => {
1498
+ if (targetBoss.name !== "空间站感染虫" || !targetBoss.skills.includes("感染空间站")) return null;
1499
+ const [sentryGun] = await ctx2.database.get("ggcevo_boss", { name: "空间站哨枪塔", isActive: true });
1500
1500
  if (sentryGun) {
1501
- const newDamage = Math.floor(initialDamage * 0.5);
1502
1501
  return {
1503
- initialDamage: newDamage,
1502
+ damageMultiplier: -0.5,
1503
+ // 50% 减伤
1504
1504
  messages: ["🛡️ 【感染空间站】生效:空间站哨枪塔存活,受到的伤害减少50%"]
1505
1505
  };
1506
1506
  }
@@ -1533,23 +1533,18 @@ function apply(ctx, config) {
1533
1533
  }, "handleMoldGrowth"),
1534
1534
  // 岗哨机枪处理
1535
1535
  handleSentryGun: /* @__PURE__ */ __name(async (ctx2, targetBoss, bossGroup) => {
1536
- if (targetBoss.name !== "空间站哨枪塔" || !targetBoss.skills.includes("岗哨机枪")) {
1536
+ if (!targetBoss.skills.includes("岗哨机枪")) {
1537
1537
  return null;
1538
1538
  }
1539
- const newCount = (targetBoss.Skillcountpoints || 0) + 1;
1540
- await ctx2.database.set(
1541
- "ggcevo_boss",
1542
- { name: targetBoss.name },
1543
- { Skillcountpoints: newCount }
1544
- );
1545
- if (newCount >= 10) {
1539
+ const currentCount = targetBoss.Skillcountpoints || 0;
1540
+ const updates = [];
1541
+ let messages = [];
1542
+ if (currentCount === 10) {
1546
1543
  const getMaxHP = /* @__PURE__ */ __name((name2) => {
1547
1544
  if (name2 === "空间站感染虫") return bossGroup.main.maxHP;
1548
1545
  const minion = bossGroup.minions.find((m) => m.name === name2);
1549
1546
  return minion?.maxHP || 0;
1550
1547
  }, "getMaxHP");
1551
- const updates = [];
1552
- const messages = [];
1553
1548
  const [infectionBug] = await ctx2.database.get("ggcevo_boss", {
1554
1549
  name: "空间站感染虫",
1555
1550
  isActive: true
@@ -1564,7 +1559,7 @@ function apply(ctx, config) {
1564
1559
  { HP: Math.min(infectionBug.HP + heal, maxHP) }
1565
1560
  )
1566
1561
  );
1567
- messages.push(`主宰回复${heal}HP`);
1562
+ messages.push(`空间站感染虫回复${heal}HP`);
1568
1563
  }
1569
1564
  const [mechaBug] = await ctx2.database.get("ggcevo_boss", {
1570
1565
  name: "机械感染虫",
@@ -1591,150 +1586,195 @@ function apply(ctx, config) {
1591
1586
  );
1592
1587
  await Promise.all(updates);
1593
1588
  return {
1594
- messages: ["🔫 【岗哨机枪】触发:" + messages.join(",")]
1589
+ messages: ["🔫 【岗哨机枪】生效:" + messages.join(",")]
1590
+ };
1591
+ }
1592
+ const newCount = currentCount + 1;
1593
+ await ctx2.database.set(
1594
+ "ggcevo_boss",
1595
+ { name: targetBoss.name },
1596
+ { Skillcountpoints: newCount }
1597
+ );
1598
+ if (newCount === 10) {
1599
+ return {
1600
+ messages: ["🔫 【岗哨机枪】达到10层!下次攻击将清空层数并治疗所有存活的异形"]
1595
1601
  };
1596
1602
  }
1597
1603
  return null;
1598
1604
  }, "handleSentryGun"),
1599
- // 结构装甲处理
1600
- handleStructuralArmor: /* @__PURE__ */ __name((targetBoss, initialDamage, weaponData) => {
1601
- if (targetBoss.name !== "空间站哨枪塔" || !targetBoss.skills.includes("结构装甲")) {
1602
- return null;
1603
- }
1605
+ // 结构装甲处理(返回减伤系数)
1606
+ handleStructuralArmor: /* @__PURE__ */ __name((targetBoss, weaponData) => {
1607
+ if (!targetBoss.skills.includes("结构装甲")) return null;
1604
1608
  let reduction = 0.2;
1605
1609
  let msg = "常规武器减伤20%";
1606
1610
  if (weaponData.type === "热能武器") {
1607
1611
  reduction = 0.4;
1608
1612
  msg = "热能武器减伤40%";
1609
1613
  }
1610
- const newDamage = Math.floor(initialDamage * (1 - reduction));
1611
1614
  return {
1612
- initialDamage: newDamage,
1615
+ damageMultiplier: -reduction,
1616
+ // 返回减伤系数
1613
1617
  messages: [`🛡️ 【结构装甲】生效:${msg}`]
1614
1618
  };
1615
1619
  }, "handleStructuralArmor"),
1616
- // 处理吸血相关效果(加法减伤 + 独立增伤)
1617
- handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss, initialDamage, currentHP, maxHP) {
1618
- if (!targetBoss.skills.includes("吸血唾液")) {
1619
- return null;
1620
- }
1621
- let messages = [];
1622
- let newDamage = initialDamage;
1620
+ // 吸血效果处理(返回综合系数)
1621
+ handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss, currentHP, maxHP) {
1622
+ if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("嗜血狂暴") || !targetBoss.skills.includes("吐血")) return null;
1623
1623
  const bloodStacks = targetBoss.Skillcountpoints || 0;
1624
- let totalReduction = 0;
1624
+ let damageMultiplier = 0;
1625
+ const messages = [];
1625
1626
  if (targetBoss.skills.includes("吸血唾液")) {
1626
- totalReduction += bloodStacks * 0.05;
1627
+ const reduction = bloodStacks * 0.05;
1628
+ damageMultiplier -= reduction;
1627
1629
  if (bloodStacks > 0) {
1628
- messages.push(`🩸 【吸血唾液】技能生效:受到的伤害-${bloodStacks * 5}%`);
1630
+ messages.push(`🩸 【吸血唾液】生效:受到的伤害-${bloodStacks * 5}%`);
1629
1631
  }
1630
1632
  }
1631
1633
  if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
1632
- totalReduction += 0.2;
1633
- messages.push(`🔥 【嗜血狂暴】技能生效:血量低于50%,进入狂暴状态,受到的伤害-20%`);
1634
- }
1635
- if (totalReduction > 0) {
1636
- newDamage = Math.floor(initialDamage * (1 - totalReduction));
1634
+ damageMultiplier -= 0.2;
1635
+ messages.push(`🔥 【嗜血狂暴】生效:血量低于50%,进入狂暴状态,受到的伤害-20%`);
1637
1636
  }
1638
1637
  if (targetBoss.skills.includes("吐血") && bloodStacks < 1) {
1639
- newDamage = Math.floor(newDamage * 1.1);
1640
- messages.push(`💔 【吐血】技能生效:无“吸血”层数,受到的伤害+10%`);
1638
+ damageMultiplier += 0.1;
1639
+ messages.push(`💔 【吐血】生效:无“吸血”层数,受到的伤害+10%`);
1641
1640
  }
1642
- return newDamage !== initialDamage ? { initialDamage: newDamage, messages } : null;
1641
+ return { damageMultiplier, messages };
1643
1642
  }, "handleBloodEffects"),
1644
1643
  handleBloodCount: /* @__PURE__ */ __name(async function(ctx2, targetBoss, currentHP, maxHP) {
1645
- if (!targetBoss.skills.includes("吸血唾液")) {
1644
+ if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食") || !targetBoss.skills.includes("嗜血狂暴")) {
1646
1645
  return null;
1647
1646
  }
1648
1647
  let messages = [];
1649
1648
  let updatedHP = currentHP;
1649
+ let newStacks;
1650
1650
  const oldStacks = targetBoss.Skillcountpoints || 0;
1651
1651
  if (oldStacks >= 10 && targetBoss.skills.includes("进食")) {
1652
1652
  const heal = Math.floor(maxHP * 0.2);
1653
1653
  updatedHP = Math.min(currentHP + heal, maxHP);
1654
1654
  await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: 0 });
1655
- messages.push(`🍽️ 【进食】技能生效:自身回复20%最大生命值(+${heal}HP),“吸血”层数清零`);
1655
+ messages.push(`🍽️ 【进食】生效:${targetBoss.name}回复20%最大生命值(+${heal}HP),“吸血”层数清零`);
1656
1656
  return { updatedHP, messages };
1657
1657
  }
1658
- let newStacks = oldStacks + 1;
1658
+ if (targetBoss.skills.includes("吸血唾液")) {
1659
+ newStacks = oldStacks + 1;
1660
+ messages.push(`🩸 【吸血唾液】生效:获得1层“吸血”`);
1661
+ }
1659
1662
  if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
1660
1663
  newStacks += 1;
1661
- messages.push(`🔥 【嗜血狂暴】技能生效:额外叠加1层“吸血”`);
1664
+ messages.push(`🔥 【嗜血狂暴】生效:额外获得1层“吸血”`);
1662
1665
  }
1663
1666
  newStacks = Math.min(newStacks, 10);
1664
1667
  if (oldStacks < 10 && newStacks >= 10) {
1665
- messages.push(`🩸 吸血层数达到${newStacks},下次攻击将触发【进食】!`);
1668
+ messages.push(`🩸 “吸血”层数达到${newStacks},下次受到攻击将触发【进食】`);
1666
1669
  }
1667
1670
  await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: newStacks });
1668
1671
  return { updatedHP, messages };
1669
1672
  }, "handleBloodCount"),
1670
- // 伽马枪辐射层数处理(攻击后触发)
1671
- handleGammaRadiation: /* @__PURE__ */ __name(async (ctx2, targetBoss, weaponName) => {
1672
- if (weaponName !== "伽马枪") return null;
1673
+ // 修改后的伽马枪辐射处理
1674
+ handleGammaRadiation: /* @__PURE__ */ __name(async (ctx2, targetBoss, weaponData) => {
1675
+ if (weaponData.name !== "伽马枪" || targetBoss.tags.includes("机械") || !targetBoss.tags.includes("生物")) {
1676
+ return null;
1677
+ }
1673
1678
  const messages = [];
1674
- const isNewRadiation = !targetBoss.skills.includes("辐射");
1675
- const newSkills = isNewRadiation ? [...targetBoss.skills, "辐射"] : targetBoss.skills;
1676
- const newVulnerability = isNewRadiation ? 1 : Math.min(targetBoss.Vulnerability + 1, 100);
1679
+ const hasRadiation = targetBoss.skills.includes("辐射");
1680
+ const currentLayers = targetBoss.Vulnerability || 0;
1681
+ const newSkills = hasRadiation ? targetBoss.skills : [...targetBoss.skills, "辐射"];
1682
+ const newLayers = hasRadiation ? Math.min(currentLayers + 1, 100) : 1;
1677
1683
  let layerMsg;
1678
- if (isNewRadiation) {
1679
- layerMsg = `☢️ 获得【辐射】效果`;
1684
+ 0;
1685
+ if (!hasRadiation) {
1686
+ layerMsg = `☢️ ${targetBoss.name} 获得【辐射】效果`;
1687
+ } else if (newLayers === currentLayers) {
1688
+ layerMsg = `☢️ 辐射层数已达上限(100层)`;
1680
1689
  } else {
1681
- if (newVulnerability === targetBoss.Vulnerability) {
1682
- layerMsg = `☢️ 辐射层数已达上限(100层)`;
1683
- } else {
1684
- const addedLayers = newVulnerability - targetBoss.Vulnerability;
1685
- layerMsg = `☢️ 辐射层数+${addedLayers}`;
1686
- }
1690
+ layerMsg = `☢️ 辐射层数叠加至${newLayers}`;
1687
1691
  }
1688
- await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, {
1689
- skills: newSkills,
1690
- Vulnerability: newVulnerability
1691
- });
1692
- messages.push(`${targetBoss.name} ${layerMsg}`);
1692
+ await ctx2.database.set(
1693
+ "ggcevo_boss",
1694
+ { name: targetBoss.name },
1695
+ {
1696
+ skills: Array.from(new Set(newSkills)),
1697
+ // 显式类型断言
1698
+ Vulnerability: newLayers
1699
+ }
1700
+ );
1701
+ messages.push(layerMsg);
1693
1702
  return { messages };
1694
1703
  }, "handleGammaRadiation"),
1695
- // 修正后的辐射伤害计算函数
1696
- calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss, baseDamage) => {
1697
- if (!targetBoss.skills.includes("辐射")) {
1698
- return {
1699
- damage: baseDamage,
1700
- messages: []
1701
- };
1702
- }
1704
+ // 伽马枪辐射计算(返回增伤系数)
1705
+ calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss) => {
1706
+ if (!targetBoss.skills.includes("辐射")) return null;
1703
1707
  const radiationLayers = targetBoss.Vulnerability || 0;
1704
- const damageMultiplier = 1 + radiationLayers * 0.01;
1705
- const amplifiedDamage = Math.floor(baseDamage * damageMultiplier);
1706
1708
  return {
1707
- damage: amplifiedDamage,
1708
- messages: radiationLayers > 0 ? [
1709
- `☢️ 【辐射】效果触发:当前${radiationLayers}层辐射,受到的伤害+${radiationLayers}%`
1710
- ] : []
1709
+ damageMultiplier: radiationLayers * 0.01,
1710
+ // 每层1%增伤
1711
+ messages: radiationLayers > 0 ? [`☢️ 【辐射】生效:当前${radiationLayers}层辐射,受到的伤害+${radiationLayers}%`] : []
1711
1712
  };
1712
1713
  }, "calculateRadiationDamage"),
1713
- // 统一处理被动技能(关键修复部分)
1714
- handlePassives: /* @__PURE__ */ __name(async function(ctx2, targetBoss, initialDamage, currentHP, maxHP, weaponName, weaponData, baseDamage, activeBosses, bossGroup) {
1714
+ // 统一处理被动技能
1715
+ handlePassives: /* @__PURE__ */ __name(async function(ctx2, targetBoss, initialDamage, currentHP, maxHP, weaponName, weaponData, activeBosses, bossGroup) {
1715
1716
  let messages = [];
1716
1717
  let skillUpdates = [];
1718
+ let totalMultiplier = 0;
1719
+ const frostEvoResult = this.handleFrostEvolution(targetBoss, weaponName, initialDamage, maxHP);
1720
+ if (frostEvoResult) {
1721
+ return {
1722
+ currentHP: frostEvoResult.updatedHP,
1723
+ messages: frostEvoResult.messages,
1724
+ skillUpdates,
1725
+ initialDamage: 0
1726
+ };
1727
+ }
1728
+ const coldImmunityResult = this.handleColdAdaptationImmunity(targetBoss, weaponName);
1729
+ if (coldImmunityResult) {
1730
+ return {
1731
+ currentHP,
1732
+ messages: coldImmunityResult.messages,
1733
+ skillUpdates,
1734
+ initialDamage: 0
1735
+ };
1736
+ }
1717
1737
  if (currentHP <= 0 && !targetBoss.skills.includes("求生本能I") && !targetBoss.skills.includes("求生本能II")) {
1718
1738
  return { currentHP, messages: [], skillUpdates: [], initialDamage };
1719
1739
  }
1720
- const radiationCalc = this.calculateRadiationDamage(targetBoss, initialDamage);
1721
- if (radiationCalc.messages.length > 0) {
1722
- messages.push(...radiationCalc.messages);
1723
- initialDamage = radiationCalc.damage;
1740
+ targetBoss.skills.forEach((skill) => {
1741
+ const config2 = passiveConfig[skill];
1742
+ if (config2 && config2.effect !== void 0 && config2.effect !== 0) {
1743
+ totalMultiplier += config2.effect;
1744
+ const effectPercent = Math.round(config2.effect * 100);
1745
+ messages.push(`📚 【${skill}】生效,受到的伤害${config2.effect > 0 ? "+" : ""}${effectPercent}%`);
1746
+ }
1747
+ });
1748
+ const infectionResult = await this.handleInfectedStation(ctx2, targetBoss);
1749
+ if (infectionResult) {
1750
+ totalMultiplier += infectionResult.damageMultiplier;
1751
+ messages.push(...infectionResult.messages);
1752
+ }
1753
+ const armorResult = this.handleStructuralArmor(targetBoss, weaponData);
1754
+ if (armorResult) {
1755
+ totalMultiplier += armorResult.damageMultiplier;
1756
+ messages.push(...armorResult.messages);
1724
1757
  }
1725
- const bloodEffectResult = this.handleBloodEffects(targetBoss, initialDamage, currentHP, maxHP);
1726
- if (bloodEffectResult) {
1727
- initialDamage = bloodEffectResult.initialDamage;
1728
- messages.push(...bloodEffectResult.messages);
1758
+ const bloodEffect = this.handleBloodEffects(targetBoss, currentHP, maxHP);
1759
+ if (bloodEffect) {
1760
+ totalMultiplier += bloodEffect.damageMultiplier;
1761
+ messages.push(...bloodEffect.messages);
1729
1762
  }
1730
- const frostEvoResult = this.handleFrostEvolution(targetBoss, weaponName, baseDamage, currentHP, maxHP);
1731
- if (frostEvoResult) {
1732
- initialDamage = frostEvoResult.initialDamage;
1733
- currentHP = frostEvoResult.updatedHP;
1734
- messages.push(...frostEvoResult.messages);
1735
- return { currentHP, messages, skillUpdates, initialDamage };
1763
+ const radiationCalc = this.calculateRadiationDamage(targetBoss);
1764
+ if (radiationCalc) {
1765
+ totalMultiplier += radiationCalc.damageMultiplier;
1766
+ messages.push(...radiationCalc.messages);
1767
+ }
1768
+ const originalMultiplier = totalMultiplier;
1769
+ totalMultiplier = Math.max(totalMultiplier, -0.99);
1770
+ if (originalMultiplier < -0.99) {
1771
+ messages.push(`⚠️ 减伤效果已达上限(99%)`);
1736
1772
  }
1737
- const frostSurroundResult = await this.handleFrostSurround(ctx2, targetBoss, currentHP, maxHP, bossGroup);
1773
+ let finalDamage = initialDamage * (1 + totalMultiplier);
1774
+ finalDamage = Math.floor(finalDamage);
1775
+ finalDamage = Math.max(finalDamage, 1);
1776
+ currentHP = targetBoss.HP - finalDamage;
1777
+ const frostSurroundResult = await this.handleFrostSurround(ctx2, targetBoss, currentHP, maxHP);
1738
1778
  if (frostSurroundResult) {
1739
1779
  currentHP = frostSurroundResult.updatedHP;
1740
1780
  messages.push(...frostSurroundResult.messages);
@@ -1746,53 +1786,44 @@ function apply(ctx, config) {
1746
1786
  messages.push(...frostRecoveryResult.messages);
1747
1787
  skillUpdates.push(...frostRecoveryResult.skillUpdates);
1748
1788
  }
1789
+ const moldResult = await this.handleMoldGrowth(ctx2, targetBoss, bossGroup);
1790
+ if (moldResult) {
1791
+ messages.push(...moldResult.messages);
1792
+ }
1793
+ const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
1794
+ if (survivalResult) {
1795
+ currentHP = survivalResult.updatedHP;
1796
+ messages.push(...survivalResult.messages);
1797
+ skillUpdates.push(...survivalResult.skillUpdates);
1798
+ }
1749
1799
  const coldAdaptResult = await this.handleColdAdaptation(ctx2, targetBoss, weaponName);
1750
1800
  if (coldAdaptResult) {
1751
1801
  messages.push(...coldAdaptResult.messages);
1752
1802
  }
1753
- const coldImmunityResult = this.handleColdAdaptationImmunity(targetBoss, weaponName);
1754
- if (coldImmunityResult) {
1755
- initialDamage = coldImmunityResult.initialDamage;
1756
- currentHP = targetBoss.HP;
1757
- messages.push(...coldImmunityResult.messages);
1758
- return { currentHP, messages, skillUpdates, initialDamage };
1759
- }
1760
1803
  const bloodCountResult = await this.handleBloodCount(ctx2, targetBoss, currentHP, maxHP);
1761
1804
  if (bloodCountResult) {
1762
1805
  currentHP = bloodCountResult.updatedHP;
1763
1806
  messages.push(...bloodCountResult.messages);
1764
1807
  }
1765
- const infectionResult = await this.handleInfectedStation(ctx2, targetBoss, initialDamage, bossGroup);
1766
- if (infectionResult) {
1767
- initialDamage = infectionResult.initialDamage;
1768
- messages.push(...infectionResult.messages);
1769
- }
1770
- const armorResult = this.handleStructuralArmor(targetBoss, initialDamage, weaponData);
1771
- if (armorResult) {
1772
- initialDamage = armorResult.initialDamage;
1773
- messages.push(...armorResult.messages);
1774
- }
1775
1808
  const sentryResult = await this.handleSentryGun(ctx2, targetBoss, bossGroup);
1776
1809
  if (sentryResult) {
1777
1810
  messages.push(...sentryResult.messages);
1778
1811
  }
1779
- const moldResult = await this.handleMoldGrowth(ctx2, targetBoss, bossGroup);
1780
- if (moldResult) {
1781
- messages.push(...moldResult.messages);
1782
- }
1783
- if (weaponName === "伽马枪" && targetBoss.tags.includes("生物") && !targetBoss.tags.includes("机械")) {
1784
- const radiationResult = await this.handleGammaRadiation(ctx2, targetBoss, weaponName);
1785
- if (radiationResult) {
1786
- messages.push(...radiationResult.messages);
1787
- }
1788
- }
1789
- const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
1790
- if (survivalResult) {
1791
- currentHP = survivalResult.updatedHP;
1792
- messages.push(...survivalResult.messages);
1793
- skillUpdates.push(...survivalResult.skillUpdates);
1812
+ const gammaRadResult = await this.handleGammaRadiation(
1813
+ ctx2,
1814
+ targetBoss,
1815
+ weaponData
1816
+ // 传入武器数据对象
1817
+ );
1818
+ if (gammaRadResult) {
1819
+ messages.push(...gammaRadResult.messages);
1794
1820
  }
1795
- return { currentHP, messages, skillUpdates, initialDamage };
1821
+ return {
1822
+ currentHP,
1823
+ messages,
1824
+ skillUpdates,
1825
+ initialDamage: finalDamage
1826
+ };
1796
1827
  }, "handlePassives"),
1797
1828
  // 应用技能更新到数据库
1798
1829
  applySkillUpdates: /* @__PURE__ */ __name(async (ctx2, skillUpdates) => {
@@ -2347,6 +2378,23 @@ function apply(ctx, config) {
2347
2378
  ].join("\n");
2348
2379
  }
2349
2380
  __name(generateUpgradePriceList, "generateUpgradePriceList");
2381
+ const weaponConfigById = {};
2382
+ for (const key in weaponConfig) {
2383
+ weaponConfigById[weaponConfig[key].id] = weaponConfig[key];
2384
+ }
2385
+ async function calculateTotalPower(handle, baseRank) {
2386
+ const weapons = await ctx.database.get("ggcevo_equipment", { handle });
2387
+ let total = baseRank;
2388
+ for (const { weaponId, level, installedMods } of weapons) {
2389
+ const weapon = weaponConfigById[weaponId];
2390
+ if (!weapon) continue;
2391
+ total += weapon.damage * 100;
2392
+ total += level * 1e3;
2393
+ total += (installedMods?.length || 0) * 2e3;
2394
+ }
2395
+ return total;
2396
+ }
2397
+ __name(calculateTotalPower, "calculateTotalPower");
2350
2398
  ctx.command("ggcevo/抽奖").action(async (argv) => {
2351
2399
  const session = argv.session;
2352
2400
  let winCount = 0;
@@ -3795,7 +3843,7 @@ ${achievementList.join("\n")}`;
3795
3843
  ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
3796
3844
  try {
3797
3845
  const session = argv.session;
3798
- if (!user) return "缺少参数,请输入“pk @指定pk玩家”。";
3846
+ if (!user) return "请输入“pk @指定pk玩家”。";
3799
3847
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
3800
3848
  if (!profile) return "🔒 需要先绑定游戏句柄。";
3801
3849
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -3818,6 +3866,8 @@ ${achievementList.join("\n")}`;
3818
3866
  ]);
3819
3867
  const initiatorRank = initiatorData[0]?.rank || 0;
3820
3868
  const targetRank = targetData[0]?.rank || 0;
3869
+ const initiatorPower = await calculateTotalPower(initiatorHandle, initiatorRank);
3870
+ const targetPower = await calculateTotalPower(targetHandle, targetRank);
3821
3871
  const initiatorRankname = initiatorData[0]?.name || session.username;
3822
3872
  const targetRankname = targetData[0]?.name || (targetUsername.name || targetUsername.user.name);
3823
3873
  let initiatorPK = {
@@ -3895,9 +3945,9 @@ ${achievementList.join("\n")}`;
3895
3945
  const targetGold = targetSign[0]?.totalRewards || 0;
3896
3946
  if (initiatorGold < 100) return "发起者需要至少100金币才能发起挑战。";
3897
3947
  if (targetGold < 100) return "对方金币不足100,无法应战。";
3898
- const rankDiff = initiatorRank - targetRank;
3899
- const clampedDiff = Math.min(Math.max(rankDiff, -1e4), 1e4);
3900
- const winRate = Math.min(Math.max(50 + clampedDiff * 5e-3, 5), 95);
3948
+ const powerDiff = initiatorPower - targetPower;
3949
+ let winRate = 50 + powerDiff / 20 * 0.01;
3950
+ winRate = Math.min(Math.max(winRate, 5), 95);
3901
3951
  const isWin = Math.random() * 100 < winRate;
3902
3952
  const stealPercentage = getRandomInt(1, 5);
3903
3953
  const goldTransfer = Math.floor(
@@ -3965,13 +4015,13 @@ ${achievementList.join("\n")}`;
3965
4015
  });
3966
4016
  const result = [
3967
4017
  `⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
3968
- `🏅 挑战者:${initiatorRankname}(积分 ${initiatorRank})`,
3969
- `🛡️ 应战者:${targetRankname}(积分 ${targetRank})`,
4018
+ `🏅 挑战者:${initiatorRankname}(战斗力 ${initiatorRank})`,
4019
+ `🛡️ 应战者:${targetRankname}(战斗力 ${targetRank})`,
3970
4020
  `📊 胜率预测:${winRate.toFixed(1)}%`,
3971
4021
  `🎰 金币变动:${stealPercentage}%`
3972
4022
  ];
3973
4023
  isWin ? result.push(`💰 您从对方的口袋里抢夺了${goldTransfer}枚金币`) : result.push(`💸 您从口袋里拿出了${goldTransfer}枚金币上交给对方`);
3974
- initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 海盗阵营奖励:获得1红晶`) : "";
4024
+ initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 海盗阵营奖励:获得1枚红晶`) : "";
3975
4025
  result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
3976
4026
  return result.join("\n");
3977
4027
  } catch (error) {
@@ -4037,7 +4087,7 @@ ${achievementList.join("\n")}`;
4037
4087
  return `状态切换冷却中,${remaining}天后再试(下次可切换时间:${new Date(lastToggle.getTime() + 3 * 864e5).toLocaleDateString("zh-CN")})。`;
4038
4088
  }
4039
4089
  const [careers] = await ctx.database.get("ggcevo_careers", { handle });
4040
- if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗,无法切换PK状态!";
4090
+ if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗阵营,无法切换PK状态!";
4041
4091
  const action = currentState ? "关闭" : "开启";
4042
4092
  await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(请在30秒内回复“是”确认)`);
4043
4093
  const confirm = await session.prompt(3e4);
@@ -4105,7 +4155,7 @@ ${Object.keys(typeStats).join("、")}`;
4105
4155
  });
4106
4156
  return [
4107
4157
  `🏪 咕咕武器库 - ${type} 🏪`,
4108
- "使用“购买 武器名称”命令进行购买",
4158
+ "使用“购买 武器名称”指令进行购买",
4109
4159
  discountRate > 0 && `🔧 当前购买折扣:${discountRate}% (武器系统 Lv${techLevel})`,
4110
4160
  "====================",
4111
4161
  ...items,
@@ -4146,7 +4196,7 @@ ${validTypes.join("、")}`;
4146
4196
  ].join("\n"));
4147
4197
  return [
4148
4198
  `💣 爆破装备库 - ${type} 💣`,
4149
- "使用“购买 物品名称”命令进行购买",
4199
+ "使用“购买 物品名称”指令进行购买",
4150
4200
  "====================",
4151
4201
  ...items,
4152
4202
  items.length === 0 ? "⚠️ 该分类下暂无可用物品" : ""
@@ -4300,7 +4350,7 @@ ${validTypes.join("、")}`;
4300
4350
  ].join("\n");
4301
4351
  }));
4302
4352
  return [
4303
- "🛡️ 您当前拥有的武器",
4353
+ `🛡️ ${handle}当前拥有的武器`,
4304
4354
  '使用"装备 武器名称"来装备武器',
4305
4355
  "⚡表示当前装备武器",
4306
4356
  "──────────────",
@@ -4481,6 +4531,11 @@ ${validTypes.join("、")}`;
4481
4531
  ctx.command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
4482
4532
  const session = argv.session;
4483
4533
  let broadcastMessage = null;
4534
+ const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4535
+ if (!profile) return "🔒 需要先绑定游戏句柄。";
4536
+ const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4537
+ const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4538
+ if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
4484
4539
  const getActiveBossNames = /* @__PURE__ */ __name(async () => {
4485
4540
  const activeBosses2 = await ctx.database.get("ggcevo_boss", { isActive: true });
4486
4541
  return activeBosses2.map((b) => b.name).join(",");
@@ -4499,11 +4554,6 @@ ${validTypes.join("、")}`;
4499
4554
  return `当前没有找到名为 ${bossName} 的可攻击目标。
4500
4555
  请攻击当前存活的异形:${activeNames || "无"}。`;
4501
4556
  }
4502
- const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4503
- if (!profile) return "🔒 需要先绑定游戏句柄。";
4504
- const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
4505
- const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
4506
- if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
4507
4557
  const config2 = ctx.config;
4508
4558
  const unlimitedBossAttack = config2.unlimitedBossAttack;
4509
4559
  if (!unlimitedBossAttack) {
@@ -4526,17 +4576,17 @@ ${validTypes.join("、")}`;
4526
4576
  if (!weaponData.isantiair && targetBoss.groupId === 5) {
4527
4577
  return "您装备的武器无法攻击空中目标!";
4528
4578
  }
4529
- const { damage: baseDamage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
4530
4579
  const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
4531
- if (!activeBosses.length) return "当前没有存活的异形,请等待1小时后刷新。";
4580
+ if (!activeBosses.length) return "当前没有存活的异形,请等待下一轮刷新。";
4532
4581
  const bossGroup = bossPool.find(
4533
4582
  (g) => g.main.name === targetBoss.name || g.minions.some((m) => m.name === targetBoss.name)
4534
4583
  );
4535
4584
  if (!bossGroup) return "无法获取异形组配置。";
4536
4585
  const maxHP = targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions.find((m) => m.name === targetBoss.name)?.maxHP || 0;
4537
- let initialDamage = Math.min(baseDamage, targetBoss.HP);
4586
+ const { damage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
4587
+ let initialDamage = Math.min(damage, targetBoss.HP);
4538
4588
  let currentHP = targetBoss.HP - initialDamage;
4539
- let healMessages = [];
4589
+ let passiveMessages = [];
4540
4590
  const passiveResult = await PassiveHandler.handlePassives(
4541
4591
  ctx,
4542
4592
  targetBoss,
@@ -4545,13 +4595,12 @@ ${validTypes.join("、")}`;
4545
4595
  maxHP,
4546
4596
  weaponName,
4547
4597
  weaponData,
4548
- baseDamage,
4549
4598
  activeBosses,
4550
4599
  bossGroup
4551
4600
  );
4552
4601
  currentHP = passiveResult.currentHP;
4553
4602
  initialDamage = passiveResult.initialDamage;
4554
- healMessages.push(...passiveResult.messages);
4603
+ passiveMessages.push(...passiveResult.messages);
4555
4604
  if (passiveResult.skillUpdates.length > 0) {
4556
4605
  await PassiveHandler.applySkillUpdates(ctx, passiveResult.skillUpdates);
4557
4606
  }
@@ -4619,7 +4668,7 @@ ${validTypes.join("、")}`;
4619
4668
  await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4620
4669
  skills: [...mainBoss.skills, "孤立无援"]
4621
4670
  });
4622
- broadcastMessages.push("💥 机械感染虫被消灭,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!");
4671
+ broadcastMessages.push("💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!");
4623
4672
  }
4624
4673
  } else {
4625
4674
  remainingMinions = await ctx.database.get("ggcevo_boss", {
@@ -4637,7 +4686,7 @@ ${validTypes.join("、")}`;
4637
4686
  await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
4638
4687
  skills: [...mainBoss.skills, "孤立无援"]
4639
4688
  });
4640
- broadcastMessages.push("💥 所有子代已阵亡,主宰进入【孤立无援】状态,受到的伤害+20%!");
4689
+ broadcastMessages.push(`💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`);
4641
4690
  }
4642
4691
  }
4643
4692
  }
@@ -4669,7 +4718,7 @@ ${validTypes.join("、")}`;
4669
4718
  handle,
4670
4719
  redcrystal: (careerData?.redcrystal || 0) + 1
4671
4720
  }], ["handle"]);
4672
- redcrystalMessage = "🔴 清洁工职业加成:获得1个红晶!";
4721
+ redcrystalMessage = "🔴 清洁工职业加成:获得1枚红晶";
4673
4722
  }
4674
4723
  const finalReward = Math.round(initialDamage * careerMultiplier);
4675
4724
  const [existingSign] = await ctx.database.get("ggcevo_sign", { handle });
@@ -4681,12 +4730,15 @@ ${validTypes.join("、")}`;
4681
4730
  const resultMessage = [
4682
4731
  `🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
4683
4732
  ...effectMessage.length > 0 ? [
4684
- `触发效果:
4685
- ${effectMessage.join("\n")}`
4733
+ `⚡ 攻击效果:
4734
+ ${effectMessage.map((m) => `▸ ${m}`).join("\n")}`
4735
+ ] : [],
4736
+ // === 新增被动效果提示区域 ===
4737
+ ...passiveMessages.length > 0 ? [
4738
+ `🛡️ 被动效果:
4739
+ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
4686
4740
  ] : [],
4687
- ...healMessages,
4688
4741
  `造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
4689
- // 修改金币显示行
4690
4742
  `获得金币:${finalReward}${careerMessage}`,
4691
4743
  redcrystalMessage,
4692
4744
  `目标剩余HP:${Math.max(currentHP, 0)}/${maxHP}`,
@@ -4699,12 +4751,11 @@ ${effectMessage.join("\n")}`
4699
4751
  await ctx.broadcast(groupId, finalBroadcast);
4700
4752
  }
4701
4753
  });
4702
- ctx.command("ggcevo/攻击假人").usage("测试当前装备武器的伤害,可添加标签和被动\n用法:攻击假人 [--标签 标签1 标签2] [--被动 被动1 被动2]").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").option("passives", "-p <passives:string> 添加BOSS被动(逗号分隔)").action(async (argv) => {
4754
+ ctx.command("ggcevo/攻击假人").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").action(async (argv) => {
4703
4755
  const session = argv.session;
4704
4756
  const { options } = argv;
4705
4757
  const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
4706
4758
  const tags = parseList(options.tags);
4707
- const passives = parseList(options.passives);
4708
4759
  const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
4709
4760
  if (!profile) return "🔒 需要先绑定游戏句柄。";
4710
4761
  const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
@@ -4720,8 +4771,6 @@ ${effectMessage.join("\n")}`
4720
4771
  HP: Infinity,
4721
4772
  type: "主宰",
4722
4773
  groupId: 0,
4723
- skills: passives || [],
4724
- // 从选项获取被动
4725
4774
  tags: tags || []
4726
4775
  // 从选项获取标签
4727
4776
  };
@@ -4733,21 +4782,22 @@ ${effectMessage.join("\n")}`
4733
4782
  {
4734
4783
  isTest: true,
4735
4784
  // 标记为测试模式
4736
- customTags: tags,
4737
- customPassives: passives
4785
+ customTags: tags
4738
4786
  }
4739
4787
  );
4740
4788
  const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
4741
4789
  const [weaponName] = weaponConfigEntry;
4742
4790
  return [
4743
- `🎯 测试攻击 ${dummyBoss.name}`,
4791
+ `🎯 攻击 ${dummyBoss.name}`,
4744
4792
  `💥 使用武器:${weaponName}`,
4745
4793
  options.tags?.length && `🏷️ 模拟标签:${tags.join(", ")}`,
4746
- options.passives?.length && `🛡️ 模拟被动:${passives.join(", ")}`,
4747
- `📊 理论伤害值:${damage}`,
4748
- hasCrit ? "✨ 触发暴击" : "",
4749
- ...effectMessage,
4750
- "⚠️ 注意:假人默认无属性,标签和被动需手动添加"
4794
+ ...effectMessage.length ? [
4795
+ "⚡ 攻击效果:",
4796
+ ...effectMessage.map((m) => `▸ ${m}`)
4797
+ // 这里添加符号
4798
+ ] : [],
4799
+ `📊 理论伤害值:${damage}${hasCrit ? " (✨ 触发暴击)" : ""}`,
4800
+ "💡 提示:使用 -t 重甲,生物…… 添加测试标签"
4751
4801
  ].filter((line) => line).join("\n");
4752
4802
  });
4753
4803
  ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
@@ -5182,9 +5232,9 @@ ${effectMessage.join("\n")}`
5182
5232
  infoCard.push("", "〓 科技研发 〓", ...activeTechs);
5183
5233
  }
5184
5234
  }
5185
- const promptMessage = careerData.group === "辛迪加海盗" ? "💡 提示:红晶可通过主动PK获得(无论胜负)" : "💡 提示:使用「转职」命令可变更职业";
5235
+ const promptMessage = careerData.group === "辛迪加海盗" ? "💡 提示:红晶可通过主动PK获得(无论胜负)" : "💡 提示:使用「转职」指令可变更职业";
5186
5236
  return [
5187
- "〓 职业档案 〓",
5237
+ `〓 ${handle}的职业档案 〓`,
5188
5238
  ...infoCard,
5189
5239
  "〓═════════〓\n" + promptMessage
5190
5240
  // 提示信息放在分隔线下方
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.16",
4
+ "version": "1.3.18",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [