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.
- package/lib/index.js +379 -329
- 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: "
|
|
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: "
|
|
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: "
|
|
600
|
+
description: "受到攻击后,若“空间站哨枪塔”存活,则为其回复1%的最大生命值"
|
|
601
601
|
},
|
|
602
602
|
"岗哨机枪": {
|
|
603
603
|
effect: 0,
|
|
604
|
-
description: "
|
|
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
|
|
612
|
+
description: "受到攻击将会获得一层“吸血”,每层“吸血”提供5%的减伤(至多10层)"
|
|
613
613
|
},
|
|
614
614
|
"进食": {
|
|
615
615
|
effect: 0,
|
|
616
|
-
description: "
|
|
616
|
+
description: "当“吸血”达到10层后,下一次受到攻击将会消耗所有层数回复自身20%的最大生命值"
|
|
617
617
|
},
|
|
618
618
|
"嗜血狂暴": {
|
|
619
619
|
effect: 0,
|
|
620
|
-
description: "血量低于50
|
|
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
|
|
1014
|
-
let
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
if (
|
|
1035
|
-
|
|
1036
|
-
|
|
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 {
|
|
1046
|
+
return {
|
|
1047
|
+
damage: Math.round(finalDamage),
|
|
1048
|
+
hasCrit,
|
|
1049
|
+
effectMessage
|
|
1050
|
+
};
|
|
1039
1051
|
}
|
|
1040
|
-
__name(
|
|
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
|
|
1058
|
-
let
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
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
|
-
|
|
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(
|
|
1066
|
-
async function
|
|
1113
|
+
__name(calculateModifiers, "calculateModifiers");
|
|
1114
|
+
async function calculateCareerAdditive(ctx2, handle, weaponType, weaponId) {
|
|
1067
1115
|
const [careerData] = await ctx2.database.get("ggcevo_careers", { handle });
|
|
1068
|
-
|
|
1069
|
-
const faction = careerData?.group;
|
|
1116
|
+
let value = 0;
|
|
1070
1117
|
let message = "";
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
multiplier = 1.05;
|
|
1118
|
+
if (careerData?.career === "警卫长") {
|
|
1119
|
+
value += 0.05;
|
|
1074
1120
|
message = "⚔️ 职业加成:警卫长(攻击伤害+5%)";
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1121
|
+
}
|
|
1122
|
+
if (careerData?.career === "武器中士") {
|
|
1123
|
+
value += 0.15;
|
|
1077
1124
|
message = "⚔️ 职业加成:武器中士(攻击伤害+15%)";
|
|
1078
1125
|
}
|
|
1079
|
-
if (
|
|
1126
|
+
if (careerData?.career === "能量武器专家") {
|
|
1080
1127
|
if (weaponType === "能量武器") {
|
|
1081
|
-
|
|
1082
|
-
message = "
|
|
1083
|
-
} else {
|
|
1084
|
-
message = "⚠️ 能量武器专家:未装备能量武器,加成未生效";
|
|
1128
|
+
value += 0.2;
|
|
1129
|
+
message = "⚔️ 职业加成:能量武器专家(能量武器伤害+20%)";
|
|
1085
1130
|
}
|
|
1086
1131
|
}
|
|
1087
|
-
if (
|
|
1132
|
+
if (careerData?.career === "纵火狂") {
|
|
1088
1133
|
if (weaponType === "热能武器") {
|
|
1089
|
-
|
|
1090
|
-
message = "
|
|
1091
|
-
} else {
|
|
1092
|
-
message = "⚠️ 纵火狂:未装备热能武器,加成未生效";
|
|
1134
|
+
value += 0.2;
|
|
1135
|
+
message = "⚔️ 职业加成:纵火狂(热能武器伤害+20%)";
|
|
1093
1136
|
}
|
|
1094
1137
|
}
|
|
1095
|
-
if (
|
|
1138
|
+
if (careerData?.career === "猩红杀手") {
|
|
1096
1139
|
if (weaponId === 7) {
|
|
1097
|
-
|
|
1098
|
-
message = "
|
|
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(
|
|
1114
|
-
async function
|
|
1115
|
-
let
|
|
1116
|
-
const
|
|
1117
|
-
const
|
|
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
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
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
|
-
|
|
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 (
|
|
1168
|
-
|
|
1169
|
-
|
|
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
|
-
|
|
1181
|
-
|
|
1182
|
-
effectMessage
|
|
1181
|
+
value,
|
|
1182
|
+
message: messages.join(",")
|
|
1183
1183
|
};
|
|
1184
1184
|
}
|
|
1185
|
-
__name(
|
|
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,
|
|
1369
|
+
handleFrostEvolution: /* @__PURE__ */ __name(function(targetBoss, weaponName, damage, maxHP) {
|
|
1365
1370
|
if (targetBoss.skills.includes("冰霜进化") && weaponName === "零度之下") {
|
|
1366
|
-
const healAmount =
|
|
1371
|
+
const healAmount = damage;
|
|
1367
1372
|
return {
|
|
1368
1373
|
updatedHP: Math.min(targetBoss.HP + healAmount, maxHP),
|
|
1369
1374
|
initialDamage: 0,
|
|
1370
|
-
|
|
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
|
|
1377
|
-
if (
|
|
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
|
-
`❄️
|
|
1404
|
-
`🌪️
|
|
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 (
|
|
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
|
-
`❄️
|
|
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: [`❄️
|
|
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.
|
|
1468
|
+
if (targetBoss.skills.includes("冷适应") && targetBoss.Skillcountpoints >= 10 && weaponName === "零度之下") {
|
|
1463
1469
|
return {
|
|
1464
1470
|
initialDamage: 0,
|
|
1465
|
-
|
|
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 >
|
|
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: [
|
|
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
|
|
1491
|
-
if (targetBoss.name !== "空间站感染虫" || !targetBoss.skills.includes("感染空间站"))
|
|
1492
|
-
|
|
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
|
-
|
|
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 (
|
|
1536
|
+
if (!targetBoss.skills.includes("岗哨机枪")) {
|
|
1537
1537
|
return null;
|
|
1538
1538
|
}
|
|
1539
|
-
const
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
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(
|
|
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: ["🔫
|
|
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,
|
|
1601
|
-
if (
|
|
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
|
-
|
|
1615
|
+
damageMultiplier: -reduction,
|
|
1616
|
+
// 返回减伤系数
|
|
1613
1617
|
messages: [`🛡️ 【结构装甲】生效:${msg}`]
|
|
1614
1618
|
};
|
|
1615
1619
|
}, "handleStructuralArmor"),
|
|
1616
|
-
//
|
|
1617
|
-
handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss,
|
|
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
|
|
1624
|
+
let damageMultiplier = 0;
|
|
1625
|
+
const messages = [];
|
|
1625
1626
|
if (targetBoss.skills.includes("吸血唾液")) {
|
|
1626
|
-
|
|
1627
|
+
const reduction = bloodStacks * 0.05;
|
|
1628
|
+
damageMultiplier -= reduction;
|
|
1627
1629
|
if (bloodStacks > 0) {
|
|
1628
|
-
messages.push(`🩸
|
|
1630
|
+
messages.push(`🩸 【吸血唾液】生效:受到的伤害-${bloodStacks * 5}%`);
|
|
1629
1631
|
}
|
|
1630
1632
|
}
|
|
1631
1633
|
if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
|
|
1632
|
-
|
|
1633
|
-
messages.push(`🔥
|
|
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
|
-
|
|
1640
|
-
messages.push(`💔
|
|
1638
|
+
damageMultiplier += 0.1;
|
|
1639
|
+
messages.push(`💔 【吐血】生效:无“吸血”层数,受到的伤害+10%`);
|
|
1641
1640
|
}
|
|
1642
|
-
return
|
|
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(`🍽️
|
|
1655
|
+
messages.push(`🍽️ 【进食】生效:${targetBoss.name}回复20%最大生命值(+${heal}HP),“吸血”层数清零`);
|
|
1656
1656
|
return { updatedHP, messages };
|
|
1657
1657
|
}
|
|
1658
|
-
|
|
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(`🔥
|
|
1664
|
+
messages.push(`🔥 【嗜血狂暴】生效:额外获得1层“吸血”`);
|
|
1662
1665
|
}
|
|
1663
1666
|
newStacks = Math.min(newStacks, 10);
|
|
1664
1667
|
if (oldStacks < 10 && newStacks >= 10) {
|
|
1665
|
-
messages.push(`🩸
|
|
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,
|
|
1672
|
-
if (
|
|
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
|
|
1675
|
-
const
|
|
1676
|
-
const
|
|
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
|
-
|
|
1679
|
-
|
|
1684
|
+
0;
|
|
1685
|
+
if (!hasRadiation) {
|
|
1686
|
+
layerMsg = `☢️ ${targetBoss.name} 获得【辐射】效果`;
|
|
1687
|
+
} else if (newLayers === currentLayers) {
|
|
1688
|
+
layerMsg = `☢️ 辐射层数已达上限(100层)`;
|
|
1680
1689
|
} else {
|
|
1681
|
-
|
|
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(
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
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
|
|
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
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
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,
|
|
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
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
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
|
|
1726
|
-
if (
|
|
1727
|
-
|
|
1728
|
-
messages.push(...
|
|
1758
|
+
const bloodEffect = this.handleBloodEffects(targetBoss, currentHP, maxHP);
|
|
1759
|
+
if (bloodEffect) {
|
|
1760
|
+
totalMultiplier += bloodEffect.damageMultiplier;
|
|
1761
|
+
messages.push(...bloodEffect.messages);
|
|
1729
1762
|
}
|
|
1730
|
-
const
|
|
1731
|
-
if (
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
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
|
-
|
|
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
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
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 {
|
|
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 "
|
|
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
|
|
3899
|
-
|
|
3900
|
-
|
|
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}(
|
|
3969
|
-
`🛡️ 应战者:${targetRankname}(
|
|
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 "
|
|
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 "
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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("💥
|
|
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(
|
|
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/攻击假人").
|
|
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
|
-
`🎯
|
|
4791
|
+
`🎯 攻击 ${dummyBoss.name}`,
|
|
4744
4792
|
`💥 使用武器:${weaponName}`,
|
|
4745
4793
|
options.tags?.length && `🏷️ 模拟标签:${tags.join(", ")}`,
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
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
|
// 提示信息放在分隔线下方
|