koishi-plugin-ggcevo-game 1.3.15 → 1.3.17
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 +472 -392
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -450,7 +450,7 @@ function apply(ctx, config) {
|
|
|
450
450
|
description: "一个小型辛迪加机器人,可以破坏电子银行账户",
|
|
451
451
|
price: 0,
|
|
452
452
|
redCrystalCost: 60,
|
|
453
|
-
effects: "
|
|
453
|
+
effects: "此物品存放于仓库,仅在处于辛迪加海盗阵营时生效。每日签到金币奖励+50%,每拥有100金币,增加1%(至多增加100%)。"
|
|
454
454
|
}
|
|
455
455
|
};
|
|
456
456
|
const modConfig = {
|
|
@@ -528,7 +528,7 @@ function apply(ctx, config) {
|
|
|
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,
|
|
@@ -625,7 +625,7 @@ function apply(ctx, config) {
|
|
|
625
625
|
},
|
|
626
626
|
"辐射": {
|
|
627
627
|
effect: 0,
|
|
628
|
-
description: "受到伽马枪攻击时会积累辐射层数,每层使受到的伤害增加1%"
|
|
628
|
+
description: "受到伽马枪攻击时会积累辐射层数,每层使受到的伤害增加1%(至多增加100%)"
|
|
629
629
|
}
|
|
630
630
|
};
|
|
631
631
|
const defineBoss = /* @__PURE__ */ __name((config2) => config2, "defineBoss");
|
|
@@ -744,28 +744,28 @@ function apply(ctx, config) {
|
|
|
744
744
|
{
|
|
745
745
|
professionName: "深空矿工",
|
|
746
746
|
effect: "每日签到获得的金币收益增加50%",
|
|
747
|
-
requirements: "当月累计签到
|
|
747
|
+
requirements: "当月累计签到7天及以上",
|
|
748
748
|
Jobtransfer: true,
|
|
749
749
|
costcoins: 1500
|
|
750
750
|
},
|
|
751
751
|
{
|
|
752
752
|
professionName: "警卫员下士",
|
|
753
753
|
effect: "攻击获得的金币增加50%",
|
|
754
|
-
requirements: "
|
|
754
|
+
requirements: "当期伤害榜累计攻击4次及以上",
|
|
755
755
|
Jobtransfer: true,
|
|
756
756
|
costcoins: 2e3
|
|
757
757
|
},
|
|
758
758
|
{
|
|
759
759
|
professionName: "警卫长",
|
|
760
760
|
effect: "攻击伤害+5%,攻击获得的金币增加100%",
|
|
761
|
-
requirements: "
|
|
761
|
+
requirements: "当期伤害榜前十名",
|
|
762
762
|
Jobtransfer: true,
|
|
763
763
|
costcoins: 3e3
|
|
764
764
|
},
|
|
765
765
|
{
|
|
766
766
|
professionName: "武器中士",
|
|
767
767
|
effect: "攻击伤害+15%",
|
|
768
|
-
requirements: "
|
|
768
|
+
requirements: "当期伤害榜累计造成100及以上伤害",
|
|
769
769
|
Jobtransfer: true,
|
|
770
770
|
costcoins: 2e3
|
|
771
771
|
},
|
|
@@ -779,7 +779,7 @@ function apply(ctx, config) {
|
|
|
779
779
|
{
|
|
780
780
|
professionName: "情报副官",
|
|
781
781
|
effect: "升级空间站科技花费的金币是原价的80%",
|
|
782
|
-
requirements: "
|
|
782
|
+
requirements: "至少一个空间站科技等级≥3级",
|
|
783
783
|
Jobtransfer: true,
|
|
784
784
|
costcoins: 3e3
|
|
785
785
|
},
|
|
@@ -815,8 +815,8 @@ function apply(ctx, config) {
|
|
|
815
815
|
const syndicatePirateConfig = [
|
|
816
816
|
{
|
|
817
817
|
professionName: "能量武器专家",
|
|
818
|
-
effect: "能量武器攻击伤害+20
|
|
819
|
-
requirements: "
|
|
818
|
+
effect: "能量武器攻击伤害+20%; 解锁MK-4激光步枪(传奇)购买权限",
|
|
819
|
+
requirements: "至少拥有一把3级及以上等级的能量武器",
|
|
820
820
|
Jobtransfer: true,
|
|
821
821
|
costcoins: 0,
|
|
822
822
|
costredcrystal: 30
|
|
@@ -824,7 +824,7 @@ function apply(ctx, config) {
|
|
|
824
824
|
{
|
|
825
825
|
professionName: "清洁工",
|
|
826
826
|
effect: "击败主宰能够根据排名获得红晶; 每次攻击额外获得红晶",
|
|
827
|
-
requirements: "
|
|
827
|
+
requirements: "当期伤害榜前二十名",
|
|
828
828
|
Jobtransfer: true,
|
|
829
829
|
costcoins: 0,
|
|
830
830
|
costredcrystal: 20
|
|
@@ -839,16 +839,16 @@ function apply(ctx, config) {
|
|
|
839
839
|
},
|
|
840
840
|
{
|
|
841
841
|
professionName: "猩红杀手",
|
|
842
|
-
effect: "
|
|
843
|
-
requirements: "
|
|
844
|
-
Jobtransfer:
|
|
842
|
+
effect: "使用“侦查步枪”造成的伤害+15%; 解锁DSR-55反器材步枪(传奇)购买权限",
|
|
843
|
+
requirements: "“侦查步枪”武器等级≥3",
|
|
844
|
+
Jobtransfer: true,
|
|
845
845
|
costcoins: 0,
|
|
846
|
-
costredcrystal:
|
|
846
|
+
costredcrystal: 30
|
|
847
847
|
},
|
|
848
848
|
{
|
|
849
849
|
professionName: "纵火狂",
|
|
850
|
-
effect: "热能武器攻击伤害+20
|
|
851
|
-
requirements: "
|
|
850
|
+
effect: "热能武器攻击伤害+20%; 解锁龙息散弹枪(传奇)购买权限",
|
|
851
|
+
requirements: "至少拥有一把3级及以上等级的热能武器",
|
|
852
852
|
Jobtransfer: true,
|
|
853
853
|
costcoins: 0,
|
|
854
854
|
costredcrystal: 30
|
|
@@ -856,7 +856,7 @@ function apply(ctx, config) {
|
|
|
856
856
|
{
|
|
857
857
|
professionName: "辛迪加财务经理",
|
|
858
858
|
effect: "每日签到能额外获得红晶",
|
|
859
|
-
requirements: "当月累计签到
|
|
859
|
+
requirements: "当月累计签到14天及以上",
|
|
860
860
|
Jobtransfer: true,
|
|
861
861
|
costcoins: 0,
|
|
862
862
|
costredcrystal: 45
|
|
@@ -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,125 +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
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
if (!rankRecord || rankRecord.rank <= 0) return 0;
|
|
1103
|
-
return Math.floor(rankRecord.rank / 400) * 0.01;
|
|
1138
|
+
if (careerData?.career === "猩红杀手") {
|
|
1139
|
+
if (weaponId === 7) {
|
|
1140
|
+
value += 0.15;
|
|
1141
|
+
message = "⚔️ 职业加成:猩红杀手(侦查步枪伤害+15%)";
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
return { value, message };
|
|
1104
1145
|
}
|
|
1105
|
-
__name(
|
|
1106
|
-
async function
|
|
1107
|
-
let
|
|
1108
|
-
const
|
|
1109
|
-
const
|
|
1110
|
-
const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
|
|
1111
|
-
const { regionId, realmId, profileId } = profile;
|
|
1112
|
-
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
1113
|
-
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
1114
|
-
const [weaponName, weaponData] = weaponConfigEntry;
|
|
1115
|
-
const weaponType = weaponData.type;
|
|
1116
|
-
let damage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
|
|
1117
|
-
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", {
|
|
1118
1151
|
handle,
|
|
1119
|
-
wishname: "
|
|
1152
|
+
wishname: "王权增幅",
|
|
1120
1153
|
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
1121
1154
|
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
1122
1155
|
});
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
damage *= 1 + totalModAdd;
|
|
1129
|
-
if (critRhythmEffect) {
|
|
1130
|
-
effectMessage.push("🎵 暴击韵律祈愿生效(暴击率+20%)");
|
|
1131
|
-
}
|
|
1132
|
-
const tagMultiplier = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
|
|
1133
|
-
damage *= 1 + tagMultiplier;
|
|
1134
|
-
const passiveMultiplier = calculatePassiveEffects(finalPassives);
|
|
1135
|
-
damage *= 1 + passiveMultiplier;
|
|
1136
|
-
const { damage: careerDamage, message: careerMessage } = await calculateCareerBonus(
|
|
1137
|
-
ctx2,
|
|
1138
|
-
handle,
|
|
1139
|
-
damage,
|
|
1140
|
-
weaponType
|
|
1141
|
-
// 新增参数
|
|
1142
|
-
);
|
|
1143
|
-
damage = careerDamage;
|
|
1144
|
-
if (careerMessage) effectMessage.push(careerMessage);
|
|
1145
|
-
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", {
|
|
1146
1161
|
handle,
|
|
1147
|
-
wishname: "
|
|
1162
|
+
wishname: "悲鸣之锋",
|
|
1148
1163
|
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
1149
1164
|
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
1150
1165
|
});
|
|
1151
|
-
|
|
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", {
|
|
1152
1172
|
handle,
|
|
1153
|
-
wishname: "
|
|
1173
|
+
wishname: "暴击韵律",
|
|
1154
1174
|
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
1155
1175
|
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
1156
1176
|
});
|
|
1157
|
-
if (
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
}
|
|
1161
|
-
if (lamentEffect) {
|
|
1162
|
-
const levelBonus = 0.1 * (equippedWeapon.level + 1);
|
|
1163
|
-
damage *= 1 + levelBonus;
|
|
1164
|
-
effectMessage.push(`🗡️ 悲鸣之锋祈愿生效(基于武器等级,攻击伤害+${(levelBonus * 100).toFixed(0)}%)`);
|
|
1165
|
-
}
|
|
1166
|
-
const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle: session.handle, rankseason: config.rankseason });
|
|
1167
|
-
const rankBonus = calculateRankBonus(rankRecord);
|
|
1168
|
-
damage *= 1 + rankBonus;
|
|
1177
|
+
if (critRhythm) {
|
|
1178
|
+
messages.push("🎵 暴击韵律(攻击暴击率+20%)");
|
|
1179
|
+
}
|
|
1169
1180
|
return {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
effectMessage
|
|
1181
|
+
value,
|
|
1182
|
+
message: messages.join(",")
|
|
1173
1183
|
};
|
|
1174
1184
|
}
|
|
1175
|
-
__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");
|
|
1176
1191
|
const initDefaultItems = {
|
|
1177
1192
|
"咕咕币": { id: 1, type: "抽奖道具", description: "用于进行抽奖" },
|
|
1178
1193
|
"兑换券": { id: 2, type: "兑换货币", description: "用于兑换赞助物品" },
|
|
@@ -1331,7 +1346,7 @@ function apply(ctx, config) {
|
|
|
1331
1346
|
const groupId = [...config.groupId];
|
|
1332
1347
|
if (totalBosses === 0) {
|
|
1333
1348
|
await activateNextBossGroup();
|
|
1334
|
-
await ctx.broadcast(groupId, `🔄
|
|
1349
|
+
await ctx.broadcast(groupId, `🔄 咕咕之战系统已初始化,首个主宰已登场!`);
|
|
1335
1350
|
return;
|
|
1336
1351
|
}
|
|
1337
1352
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1351,20 +1366,21 @@ function apply(ctx, config) {
|
|
|
1351
1366
|
}, 60 * 1e3);
|
|
1352
1367
|
const PassiveHandler = {
|
|
1353
1368
|
// 冰霜进化处理(免疫冰霜伤害)
|
|
1354
|
-
handleFrostEvolution: /* @__PURE__ */ __name(function(targetBoss, weaponName,
|
|
1369
|
+
handleFrostEvolution: /* @__PURE__ */ __name(function(targetBoss, weaponName, damage, maxHP) {
|
|
1355
1370
|
if (targetBoss.skills.includes("冰霜进化") && weaponName === "零度之下") {
|
|
1356
|
-
const healAmount =
|
|
1371
|
+
const healAmount = damage;
|
|
1357
1372
|
return {
|
|
1358
1373
|
updatedHP: Math.min(targetBoss.HP + healAmount, maxHP),
|
|
1359
1374
|
initialDamage: 0,
|
|
1360
|
-
|
|
1375
|
+
// 直接设置伤害为0
|
|
1376
|
+
messages: [`❄️ 【冰霜进化】生效:免疫冰霜伤害,${targetBoss.name}回复 ${healAmount} 生命值`]
|
|
1361
1377
|
};
|
|
1362
1378
|
}
|
|
1363
1379
|
return null;
|
|
1364
1380
|
}, "handleFrostEvolution"),
|
|
1365
1381
|
// 冰霜环绕处理(主宰专用)
|
|
1366
|
-
handleFrostSurround: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP
|
|
1367
|
-
if (
|
|
1382
|
+
handleFrostSurround: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP) => {
|
|
1383
|
+
if (!targetBoss.skills.includes("冰霜环绕") || currentHP <= 0 || // 新增血量必须大于0的判断
|
|
1368
1384
|
currentHP / maxHP > 0.3) {
|
|
1369
1385
|
return null;
|
|
1370
1386
|
}
|
|
@@ -1390,14 +1406,14 @@ function apply(ctx, config) {
|
|
|
1390
1406
|
updatedHP,
|
|
1391
1407
|
skillUpdates,
|
|
1392
1408
|
messages: [
|
|
1393
|
-
`❄️
|
|
1394
|
-
`🌪️
|
|
1409
|
+
`❄️ 【冰霜环绕】生效,${targetBoss.name}回复45%最大生命值(+${healAmount}HP)`,
|
|
1410
|
+
`🌪️ 警告!【寒霜地狱】降临,所有存活的异形获得30%减伤效果`
|
|
1395
1411
|
]
|
|
1396
1412
|
};
|
|
1397
1413
|
}, "handleFrostSurround"),
|
|
1398
1414
|
// 冰霜回复处理(子代专用)
|
|
1399
1415
|
handleFrostRecovery: /* @__PURE__ */ __name(async (ctx2, targetBoss, currentHP, maxHP, activeBosses, bossGroup) => {
|
|
1400
|
-
if (
|
|
1416
|
+
if (!targetBoss.skills.includes("冰霜回复") || currentHP <= 0 || // 新增血量必须大于0的判断
|
|
1401
1417
|
currentHP / maxHP > 0.3) {
|
|
1402
1418
|
return null;
|
|
1403
1419
|
}
|
|
@@ -1423,7 +1439,7 @@ function apply(ctx, config) {
|
|
|
1423
1439
|
remove: ["冰霜回复"]
|
|
1424
1440
|
}],
|
|
1425
1441
|
messages: [
|
|
1426
|
-
`❄️
|
|
1442
|
+
`❄️ 【冰霜回复】生效,${targetBoss.name}回复40%最大生命值(+${selfHeal}HP),${mainBoss.name}回复10%最大生命值(+${mainHeal}HP)`
|
|
1427
1443
|
]
|
|
1428
1444
|
};
|
|
1429
1445
|
}, "handleFrostRecovery"),
|
|
@@ -1442,24 +1458,25 @@ function apply(ctx, config) {
|
|
|
1442
1458
|
tags: newtags
|
|
1443
1459
|
});
|
|
1444
1460
|
return {
|
|
1445
|
-
messages: [`❄️
|
|
1461
|
+
messages: [`❄️ 【冷适应】生效,${targetBoss.name}获得「惧热」标签`]
|
|
1446
1462
|
};
|
|
1447
1463
|
}
|
|
1448
1464
|
return null;
|
|
1449
1465
|
}, "handleColdAdaptation"),
|
|
1450
|
-
//
|
|
1466
|
+
// 冷适应免疫处理
|
|
1451
1467
|
handleColdAdaptationImmunity: /* @__PURE__ */ __name(function(targetBoss, weaponName) {
|
|
1452
|
-
if (targetBoss.
|
|
1468
|
+
if (targetBoss.skills.includes("冷适应") && targetBoss.Skillcountpoints >= 10 && weaponName === "零度之下") {
|
|
1453
1469
|
return {
|
|
1454
1470
|
initialDamage: 0,
|
|
1455
|
-
|
|
1471
|
+
// 直接设置伤害为0
|
|
1472
|
+
messages: [`❄️ 【冷适应】生效:免疫寒冷伤害`]
|
|
1456
1473
|
};
|
|
1457
1474
|
}
|
|
1458
1475
|
return null;
|
|
1459
1476
|
}, "handleColdAdaptationImmunity"),
|
|
1460
1477
|
// 求生本能处理
|
|
1461
1478
|
handleSurvivalInstinct: /* @__PURE__ */ __name(function(targetBoss, currentHP, maxHP) {
|
|
1462
|
-
if (currentHP >
|
|
1479
|
+
if (currentHP > 0) return null;
|
|
1463
1480
|
let effect = null;
|
|
1464
1481
|
if (targetBoss.skills.includes("求生本能I")) {
|
|
1465
1482
|
effect = { heal: maxHP * 0.3, skill: "求生本能I" };
|
|
@@ -1469,29 +1486,22 @@ function apply(ctx, config) {
|
|
|
1469
1486
|
if (!effect) return null;
|
|
1470
1487
|
return {
|
|
1471
1488
|
updatedHP: effect.heal,
|
|
1472
|
-
messages: [
|
|
1489
|
+
messages: [`【${effect.skill}】生效,${targetBoss.name}瞬间回复${effect.heal}生命值!`],
|
|
1473
1490
|
skillUpdates: [{
|
|
1474
1491
|
name: targetBoss.name,
|
|
1475
1492
|
remove: [effect.skill]
|
|
1476
1493
|
}]
|
|
1477
1494
|
};
|
|
1478
1495
|
}, "handleSurvivalInstinct"),
|
|
1479
|
-
//
|
|
1480
|
-
handleInfectedStation: /* @__PURE__ */ __name(async (ctx2, targetBoss
|
|
1481
|
-
if (targetBoss.name !== "空间站感染虫" || !targetBoss.skills.includes("感染空间站"))
|
|
1482
|
-
|
|
1483
|
-
}
|
|
1484
|
-
const sentryConfig = bossGroup.minions.find((m) => m.name === "空间站哨枪塔");
|
|
1485
|
-
if (!sentryConfig) return null;
|
|
1486
|
-
const [sentryGun] = await ctx2.database.get("ggcevo_boss", {
|
|
1487
|
-
name: "空间站哨枪塔",
|
|
1488
|
-
isActive: true
|
|
1489
|
-
});
|
|
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 });
|
|
1490
1500
|
if (sentryGun) {
|
|
1491
|
-
const newDamage = Math.floor(initialDamage * 0.5);
|
|
1492
1501
|
return {
|
|
1493
|
-
|
|
1494
|
-
|
|
1502
|
+
damageMultiplier: -0.5,
|
|
1503
|
+
// 50% 减伤
|
|
1504
|
+
messages: ["🛡️ 【感染空间站】生效:空间站哨枪塔存活,受到的伤害减少50%"]
|
|
1495
1505
|
};
|
|
1496
1506
|
}
|
|
1497
1507
|
return null;
|
|
@@ -1523,23 +1533,18 @@ function apply(ctx, config) {
|
|
|
1523
1533
|
}, "handleMoldGrowth"),
|
|
1524
1534
|
// 岗哨机枪处理
|
|
1525
1535
|
handleSentryGun: /* @__PURE__ */ __name(async (ctx2, targetBoss, bossGroup) => {
|
|
1526
|
-
if (
|
|
1536
|
+
if (!targetBoss.skills.includes("岗哨机枪")) {
|
|
1527
1537
|
return null;
|
|
1528
1538
|
}
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
{ Skillcountpoints: newCount }
|
|
1534
|
-
);
|
|
1535
|
-
if (newCount >= 10) {
|
|
1539
|
+
const currentCount = targetBoss.Skillcountpoints || 0;
|
|
1540
|
+
const updates = [];
|
|
1541
|
+
let messages = [];
|
|
1542
|
+
if (currentCount === 10) {
|
|
1536
1543
|
const getMaxHP = /* @__PURE__ */ __name((name2) => {
|
|
1537
1544
|
if (name2 === "空间站感染虫") return bossGroup.main.maxHP;
|
|
1538
1545
|
const minion = bossGroup.minions.find((m) => m.name === name2);
|
|
1539
1546
|
return minion?.maxHP || 0;
|
|
1540
1547
|
}, "getMaxHP");
|
|
1541
|
-
const updates = [];
|
|
1542
|
-
const messages = [];
|
|
1543
1548
|
const [infectionBug] = await ctx2.database.get("ggcevo_boss", {
|
|
1544
1549
|
name: "空间站感染虫",
|
|
1545
1550
|
isActive: true
|
|
@@ -1554,7 +1559,7 @@ function apply(ctx, config) {
|
|
|
1554
1559
|
{ HP: Math.min(infectionBug.HP + heal, maxHP) }
|
|
1555
1560
|
)
|
|
1556
1561
|
);
|
|
1557
|
-
messages.push(
|
|
1562
|
+
messages.push(`空间站感染虫回复${heal}HP`);
|
|
1558
1563
|
}
|
|
1559
1564
|
const [mechaBug] = await ctx2.database.get("ggcevo_boss", {
|
|
1560
1565
|
name: "机械感染虫",
|
|
@@ -1581,132 +1586,193 @@ function apply(ctx, config) {
|
|
|
1581
1586
|
);
|
|
1582
1587
|
await Promise.all(updates);
|
|
1583
1588
|
return {
|
|
1584
|
-
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层!下次攻击将清空层数并治疗所有存活的异形"]
|
|
1585
1601
|
};
|
|
1586
1602
|
}
|
|
1587
1603
|
return null;
|
|
1588
1604
|
}, "handleSentryGun"),
|
|
1589
|
-
//
|
|
1590
|
-
handleStructuralArmor: /* @__PURE__ */ __name((targetBoss,
|
|
1591
|
-
if (
|
|
1592
|
-
return null;
|
|
1593
|
-
}
|
|
1605
|
+
// 结构装甲处理(返回减伤系数)
|
|
1606
|
+
handleStructuralArmor: /* @__PURE__ */ __name((targetBoss, weaponData) => {
|
|
1607
|
+
if (!targetBoss.skills.includes("结构装甲")) return null;
|
|
1594
1608
|
let reduction = 0.2;
|
|
1595
1609
|
let msg = "常规武器减伤20%";
|
|
1596
1610
|
if (weaponData.type === "热能武器") {
|
|
1597
1611
|
reduction = 0.4;
|
|
1598
1612
|
msg = "热能武器减伤40%";
|
|
1599
1613
|
}
|
|
1600
|
-
const newDamage = Math.floor(initialDamage * (1 - reduction));
|
|
1601
1614
|
return {
|
|
1602
|
-
|
|
1615
|
+
damageMultiplier: -reduction,
|
|
1616
|
+
// 返回减伤系数
|
|
1603
1617
|
messages: [`🛡️ 【结构装甲】生效:${msg}`]
|
|
1604
1618
|
};
|
|
1605
1619
|
}, "handleStructuralArmor"),
|
|
1606
|
-
//
|
|
1607
|
-
handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss,
|
|
1608
|
-
|
|
1609
|
-
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;
|
|
1610
1623
|
const bloodStacks = targetBoss.Skillcountpoints || 0;
|
|
1611
|
-
let
|
|
1624
|
+
let damageMultiplier = 0;
|
|
1625
|
+
const messages = [];
|
|
1612
1626
|
if (targetBoss.skills.includes("吸血唾液")) {
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
}
|
|
1627
|
+
const reduction = bloodStacks * 0.05;
|
|
1628
|
+
damageMultiplier -= reduction;
|
|
1629
|
+
messages.push(`🩸 【吸血唾液】生效:受到的伤害-${bloodStacks * 5}%`);
|
|
1617
1630
|
}
|
|
1618
1631
|
if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
|
|
1619
|
-
|
|
1620
|
-
messages.push(`🔥
|
|
1621
|
-
}
|
|
1622
|
-
if (totalReduction > 0) {
|
|
1623
|
-
newDamage = Math.floor(initialDamage * (1 - totalReduction));
|
|
1632
|
+
damageMultiplier -= 0.2;
|
|
1633
|
+
messages.push(`🔥 【嗜血狂暴】生效:血量低于50%,进入狂暴状态,受到的伤害-20%`);
|
|
1624
1634
|
}
|
|
1625
1635
|
if (targetBoss.skills.includes("吐血") && bloodStacks < 1) {
|
|
1626
|
-
|
|
1627
|
-
messages.push(`💔
|
|
1636
|
+
damageMultiplier += 0.1;
|
|
1637
|
+
messages.push(`💔 【吐血】生效:无“吸血”层数,受到的伤害+10%`);
|
|
1628
1638
|
}
|
|
1629
|
-
return
|
|
1639
|
+
return { damageMultiplier, messages };
|
|
1630
1640
|
}, "handleBloodEffects"),
|
|
1631
1641
|
handleBloodCount: /* @__PURE__ */ __name(async function(ctx2, targetBoss, currentHP, maxHP) {
|
|
1642
|
+
if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食") || !targetBoss.skills.includes("嗜血狂暴")) {
|
|
1643
|
+
return null;
|
|
1644
|
+
}
|
|
1632
1645
|
let messages = [];
|
|
1633
1646
|
let updatedHP = currentHP;
|
|
1647
|
+
let newStacks;
|
|
1634
1648
|
const oldStacks = targetBoss.Skillcountpoints || 0;
|
|
1635
1649
|
if (oldStacks >= 10 && targetBoss.skills.includes("进食")) {
|
|
1636
1650
|
const heal = Math.floor(maxHP * 0.2);
|
|
1637
1651
|
updatedHP = Math.min(currentHP + heal, maxHP);
|
|
1638
1652
|
await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: 0 });
|
|
1639
|
-
messages.push(`🍽️
|
|
1653
|
+
messages.push(`🍽️ 【进食】生效:${targetBoss.name}回复20%最大生命值(+${heal}HP),“吸血”层数清零`);
|
|
1640
1654
|
return { updatedHP, messages };
|
|
1641
1655
|
}
|
|
1642
|
-
|
|
1656
|
+
if (targetBoss.skills.includes("吸血唾液")) {
|
|
1657
|
+
newStacks = oldStacks + 1;
|
|
1658
|
+
messages.push(`🩸 【吸血唾液】生效:获得1层“吸血”`);
|
|
1659
|
+
}
|
|
1643
1660
|
if (targetBoss.skills.includes("嗜血狂暴") && currentHP / maxHP < 0.5) {
|
|
1644
1661
|
newStacks += 1;
|
|
1645
|
-
messages.push(`🔥
|
|
1662
|
+
messages.push(`🔥 【嗜血狂暴】生效:额外获得1层“吸血”`);
|
|
1646
1663
|
}
|
|
1647
1664
|
newStacks = Math.min(newStacks, 10);
|
|
1648
1665
|
if (oldStacks < 10 && newStacks >= 10) {
|
|
1649
|
-
messages.push(`🩸
|
|
1666
|
+
messages.push(`🩸 “吸血”层数达到${newStacks},下次受到攻击将触发【进食】`);
|
|
1650
1667
|
}
|
|
1651
1668
|
await ctx2.database.set("ggcevo_boss", { name: targetBoss.name }, { Skillcountpoints: newStacks });
|
|
1652
1669
|
return { updatedHP, messages };
|
|
1653
1670
|
}, "handleBloodCount"),
|
|
1654
|
-
//
|
|
1655
|
-
handleGammaRadiation: /* @__PURE__ */ __name(async (ctx2, targetBoss,
|
|
1656
|
-
if (
|
|
1671
|
+
// 修改后的伽马枪辐射处理
|
|
1672
|
+
handleGammaRadiation: /* @__PURE__ */ __name(async (ctx2, targetBoss, weaponData) => {
|
|
1673
|
+
if (weaponData.name !== "伽马枪" || targetBoss.tags.includes("机械") || !targetBoss.tags.includes("生物")) {
|
|
1674
|
+
return null;
|
|
1675
|
+
}
|
|
1657
1676
|
const messages = [];
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1677
|
+
const hasRadiation = targetBoss.skills.includes("辐射");
|
|
1678
|
+
const currentLayers = targetBoss.Vulnerability || 0;
|
|
1679
|
+
const newSkills = hasRadiation ? targetBoss.skills : [...targetBoss.skills, "辐射"];
|
|
1680
|
+
const newLayers = hasRadiation ? Math.min(currentLayers + 1, 100) : 1;
|
|
1681
|
+
let layerMsg;
|
|
1682
|
+
0;
|
|
1683
|
+
if (!hasRadiation) {
|
|
1684
|
+
layerMsg = `☢️ ${targetBoss.name} 获得【辐射】效果`;
|
|
1685
|
+
} else if (newLayers === currentLayers) {
|
|
1686
|
+
layerMsg = `☢️ 辐射层数已达上限(100层)`;
|
|
1687
|
+
} else {
|
|
1688
|
+
layerMsg = `☢️ 辐射层数叠加至${newLayers}`;
|
|
1689
|
+
}
|
|
1690
|
+
await ctx2.database.set(
|
|
1691
|
+
"ggcevo_boss",
|
|
1692
|
+
{ name: targetBoss.name },
|
|
1693
|
+
{
|
|
1694
|
+
skills: Array.from(new Set(newSkills)),
|
|
1695
|
+
// 显式类型断言
|
|
1696
|
+
Vulnerability: newLayers
|
|
1697
|
+
}
|
|
1698
|
+
);
|
|
1699
|
+
messages.push(layerMsg);
|
|
1665
1700
|
return { messages };
|
|
1666
1701
|
}, "handleGammaRadiation"),
|
|
1667
|
-
//
|
|
1668
|
-
calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss
|
|
1669
|
-
if (!targetBoss.skills.includes("辐射"))
|
|
1670
|
-
return {
|
|
1671
|
-
damage: baseDamage,
|
|
1672
|
-
messages: []
|
|
1673
|
-
};
|
|
1674
|
-
}
|
|
1702
|
+
// 伽马枪辐射计算(返回增伤系数)
|
|
1703
|
+
calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss) => {
|
|
1704
|
+
if (!targetBoss.skills.includes("辐射")) return null;
|
|
1675
1705
|
const radiationLayers = targetBoss.Vulnerability || 0;
|
|
1676
|
-
const damageMultiplier = 1 + radiationLayers * 0.01;
|
|
1677
|
-
const amplifiedDamage = Math.floor(baseDamage * damageMultiplier);
|
|
1678
1706
|
return {
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
] : []
|
|
1707
|
+
damageMultiplier: radiationLayers * 0.01,
|
|
1708
|
+
// 每层1%增伤
|
|
1709
|
+
messages: radiationLayers > 0 ? [`☢️ 【辐射】生效:当前${radiationLayers}层辐射,受到的伤害+${radiationLayers}%`] : []
|
|
1683
1710
|
};
|
|
1684
1711
|
}, "calculateRadiationDamage"),
|
|
1685
|
-
//
|
|
1686
|
-
handlePassives: /* @__PURE__ */ __name(async function(ctx2, targetBoss, initialDamage, currentHP, maxHP, weaponName, weaponData,
|
|
1712
|
+
// 统一处理被动技能
|
|
1713
|
+
handlePassives: /* @__PURE__ */ __name(async function(ctx2, targetBoss, initialDamage, currentHP, maxHP, weaponName, weaponData, activeBosses, bossGroup) {
|
|
1687
1714
|
let messages = [];
|
|
1688
1715
|
let skillUpdates = [];
|
|
1716
|
+
let totalMultiplier = 0;
|
|
1717
|
+
const frostEvoResult = this.handleFrostEvolution(targetBoss, weaponName, initialDamage, maxHP);
|
|
1718
|
+
if (frostEvoResult) {
|
|
1719
|
+
return {
|
|
1720
|
+
currentHP: frostEvoResult.updatedHP,
|
|
1721
|
+
messages: frostEvoResult.messages,
|
|
1722
|
+
skillUpdates,
|
|
1723
|
+
initialDamage: 0
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
const coldImmunityResult = this.handleColdAdaptationImmunity(targetBoss, weaponName);
|
|
1727
|
+
if (coldImmunityResult) {
|
|
1728
|
+
return {
|
|
1729
|
+
currentHP,
|
|
1730
|
+
messages: coldImmunityResult.messages,
|
|
1731
|
+
skillUpdates,
|
|
1732
|
+
initialDamage: 0
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1689
1735
|
if (currentHP <= 0 && !targetBoss.skills.includes("求生本能I") && !targetBoss.skills.includes("求生本能II")) {
|
|
1690
1736
|
return { currentHP, messages: [], skillUpdates: [], initialDamage };
|
|
1691
1737
|
}
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1738
|
+
targetBoss.skills.forEach((skill) => {
|
|
1739
|
+
const config2 = passiveConfig[skill];
|
|
1740
|
+
if (config2 && config2.effect !== void 0 && config2.effect !== 0) {
|
|
1741
|
+
totalMultiplier += config2.effect;
|
|
1742
|
+
const effectPercent = Math.round(config2.effect * 100);
|
|
1743
|
+
messages.push(`📚 【${skill}】生效,受到的伤害${config2.effect > 0 ? "+" : ""}${effectPercent}%`);
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
const infectionResult = await this.handleInfectedStation(ctx2, targetBoss);
|
|
1747
|
+
if (infectionResult) {
|
|
1748
|
+
totalMultiplier += infectionResult.damageMultiplier;
|
|
1749
|
+
messages.push(...infectionResult.messages);
|
|
1696
1750
|
}
|
|
1697
|
-
const
|
|
1698
|
-
if (
|
|
1699
|
-
|
|
1700
|
-
messages.push(...
|
|
1751
|
+
const armorResult = this.handleStructuralArmor(targetBoss, weaponData);
|
|
1752
|
+
if (armorResult) {
|
|
1753
|
+
totalMultiplier += armorResult.damageMultiplier;
|
|
1754
|
+
messages.push(...armorResult.messages);
|
|
1701
1755
|
}
|
|
1702
|
-
const
|
|
1703
|
-
if (
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1756
|
+
const bloodEffect = this.handleBloodEffects(targetBoss, currentHP, maxHP);
|
|
1757
|
+
if (bloodEffect) {
|
|
1758
|
+
totalMultiplier += bloodEffect.damageMultiplier;
|
|
1759
|
+
messages.push(...bloodEffect.messages);
|
|
1760
|
+
}
|
|
1761
|
+
const radiationCalc = this.calculateRadiationDamage(targetBoss);
|
|
1762
|
+
if (radiationCalc) {
|
|
1763
|
+
totalMultiplier += radiationCalc.damageMultiplier;
|
|
1764
|
+
messages.push(...radiationCalc.messages);
|
|
1708
1765
|
}
|
|
1709
|
-
const
|
|
1766
|
+
const originalMultiplier = totalMultiplier;
|
|
1767
|
+
totalMultiplier = Math.max(totalMultiplier, -0.99);
|
|
1768
|
+
if (originalMultiplier < -0.99) {
|
|
1769
|
+
messages.push(`⚠️ 减伤效果已达上限(99%)`);
|
|
1770
|
+
}
|
|
1771
|
+
let finalDamage = initialDamage * (1 + totalMultiplier);
|
|
1772
|
+
finalDamage = Math.floor(finalDamage);
|
|
1773
|
+
finalDamage = Math.max(finalDamage, 1);
|
|
1774
|
+
currentHP = targetBoss.HP - finalDamage;
|
|
1775
|
+
const frostSurroundResult = await this.handleFrostSurround(ctx2, targetBoss, currentHP, maxHP);
|
|
1710
1776
|
if (frostSurroundResult) {
|
|
1711
1777
|
currentHP = frostSurroundResult.updatedHP;
|
|
1712
1778
|
messages.push(...frostSurroundResult.messages);
|
|
@@ -1718,53 +1784,44 @@ function apply(ctx, config) {
|
|
|
1718
1784
|
messages.push(...frostRecoveryResult.messages);
|
|
1719
1785
|
skillUpdates.push(...frostRecoveryResult.skillUpdates);
|
|
1720
1786
|
}
|
|
1787
|
+
const moldResult = await this.handleMoldGrowth(ctx2, targetBoss, bossGroup);
|
|
1788
|
+
if (moldResult) {
|
|
1789
|
+
messages.push(...moldResult.messages);
|
|
1790
|
+
}
|
|
1791
|
+
const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
|
|
1792
|
+
if (survivalResult) {
|
|
1793
|
+
currentHP = survivalResult.updatedHP;
|
|
1794
|
+
messages.push(...survivalResult.messages);
|
|
1795
|
+
skillUpdates.push(...survivalResult.skillUpdates);
|
|
1796
|
+
}
|
|
1721
1797
|
const coldAdaptResult = await this.handleColdAdaptation(ctx2, targetBoss, weaponName);
|
|
1722
1798
|
if (coldAdaptResult) {
|
|
1723
1799
|
messages.push(...coldAdaptResult.messages);
|
|
1724
1800
|
}
|
|
1725
|
-
const coldImmunityResult = this.handleColdAdaptationImmunity(targetBoss, weaponName);
|
|
1726
|
-
if (coldImmunityResult) {
|
|
1727
|
-
initialDamage = coldImmunityResult.initialDamage;
|
|
1728
|
-
currentHP = targetBoss.HP;
|
|
1729
|
-
messages.push(...coldImmunityResult.messages);
|
|
1730
|
-
return { currentHP, messages, skillUpdates, initialDamage };
|
|
1731
|
-
}
|
|
1732
1801
|
const bloodCountResult = await this.handleBloodCount(ctx2, targetBoss, currentHP, maxHP);
|
|
1733
1802
|
if (bloodCountResult) {
|
|
1734
1803
|
currentHP = bloodCountResult.updatedHP;
|
|
1735
1804
|
messages.push(...bloodCountResult.messages);
|
|
1736
1805
|
}
|
|
1737
|
-
const infectionResult = await this.handleInfectedStation(ctx2, targetBoss, initialDamage, bossGroup);
|
|
1738
|
-
if (infectionResult) {
|
|
1739
|
-
initialDamage = infectionResult.initialDamage;
|
|
1740
|
-
messages.push(...infectionResult.messages);
|
|
1741
|
-
}
|
|
1742
|
-
const armorResult = this.handleStructuralArmor(targetBoss, initialDamage, weaponData);
|
|
1743
|
-
if (armorResult) {
|
|
1744
|
-
initialDamage = armorResult.initialDamage;
|
|
1745
|
-
messages.push(...armorResult.messages);
|
|
1746
|
-
}
|
|
1747
1806
|
const sentryResult = await this.handleSentryGun(ctx2, targetBoss, bossGroup);
|
|
1748
1807
|
if (sentryResult) {
|
|
1749
1808
|
messages.push(...sentryResult.messages);
|
|
1750
1809
|
}
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
const survivalResult = this.handleSurvivalInstinct(targetBoss, currentHP, maxHP);
|
|
1762
|
-
if (survivalResult) {
|
|
1763
|
-
currentHP = survivalResult.updatedHP;
|
|
1764
|
-
messages.push(...survivalResult.messages);
|
|
1765
|
-
skillUpdates.push(...survivalResult.skillUpdates);
|
|
1810
|
+
const gammaRadResult = await this.handleGammaRadiation(
|
|
1811
|
+
ctx2,
|
|
1812
|
+
targetBoss,
|
|
1813
|
+
weaponData
|
|
1814
|
+
// 传入武器数据对象
|
|
1815
|
+
);
|
|
1816
|
+
if (gammaRadResult) {
|
|
1817
|
+
messages.push(...gammaRadResult.messages);
|
|
1766
1818
|
}
|
|
1767
|
-
return {
|
|
1819
|
+
return {
|
|
1820
|
+
currentHP,
|
|
1821
|
+
messages,
|
|
1822
|
+
skillUpdates,
|
|
1823
|
+
initialDamage: finalDamage
|
|
1824
|
+
};
|
|
1768
1825
|
}, "handlePassives"),
|
|
1769
1826
|
// 应用技能更新到数据库
|
|
1770
1827
|
applySkillUpdates: /* @__PURE__ */ __name(async (ctx2, skillUpdates) => {
|
|
@@ -1968,42 +2025,39 @@ function apply(ctx, config) {
|
|
|
1968
2025
|
switch (profession) {
|
|
1969
2026
|
case "深空矿工":
|
|
1970
2027
|
return {
|
|
1971
|
-
success: signData?.monthlyDays >=
|
|
1972
|
-
message:
|
|
2028
|
+
success: signData?.monthlyDays >= 7,
|
|
2029
|
+
message: `需要当月累计签到7天及以上(当前${signData?.monthlyDays || 0}天)`
|
|
1973
2030
|
};
|
|
1974
2031
|
case "警卫员下士":
|
|
1975
2032
|
if (!mainBoss) return { success: false, message: "当前暂无伤害榜。" };
|
|
1976
2033
|
return {
|
|
1977
|
-
success: totalAttack >=
|
|
1978
|
-
message:
|
|
2034
|
+
success: totalAttack >= 4,
|
|
2035
|
+
message: `需要当期伤害榜累计攻击4次及以上(当前${totalAttack}次)`
|
|
1979
2036
|
};
|
|
1980
2037
|
case "警卫长": {
|
|
1981
2038
|
if (careerData?.career !== "警卫员下士") {
|
|
1982
2039
|
return { success: false, message: "需要当前职业为警卫员下士" };
|
|
1983
2040
|
}
|
|
1984
2041
|
if (!mainBoss) return { success: false, message: "当前暂无伤害榜。" };
|
|
1985
|
-
const
|
|
1986
|
-
|
|
1987
|
-
handle
|
|
1988
|
-
}).orderBy("totalDamage", "desc").limit(3).execute();
|
|
1989
|
-
const isInTop3 = top3.some((r) => r.handle === handle);
|
|
2042
|
+
const top10 = await ctx2.database.select("ggcevo_boss_damage").where({ bossGroupId: mainBoss.groupId }).orderBy("totalDamage", "desc").limit(10).execute();
|
|
2043
|
+
const isInTop10 = top10.some((r) => r.handle === handle);
|
|
1990
2044
|
return {
|
|
1991
|
-
success:
|
|
1992
|
-
message: "
|
|
2045
|
+
success: isInTop10,
|
|
2046
|
+
message: "需要当期伤害榜前十名"
|
|
1993
2047
|
};
|
|
1994
2048
|
}
|
|
1995
2049
|
case "武器中士":
|
|
1996
2050
|
if (!mainBoss) return { success: false, message: "当前暂无伤害榜。" };
|
|
1997
2051
|
return {
|
|
1998
|
-
success: totalDamage >=
|
|
1999
|
-
message:
|
|
2052
|
+
success: totalDamage >= 100,
|
|
2053
|
+
message: `需要当期伤害榜累计造成100及以上伤害(当前${totalDamage})`
|
|
2000
2054
|
};
|
|
2001
2055
|
case "情报副官":
|
|
2002
2056
|
const techs = await ctx2.database.get("ggcevo_tech", { handle });
|
|
2003
2057
|
const hasValidTech = techs.some((t) => t.level >= 3);
|
|
2004
2058
|
return {
|
|
2005
2059
|
success: hasValidTech,
|
|
2006
|
-
message: hasValidTech ? "" : "
|
|
2060
|
+
message: hasValidTech ? "" : "需要至少一个空间站科技等级≥3级"
|
|
2007
2061
|
};
|
|
2008
2062
|
case "能量武器专家":
|
|
2009
2063
|
const hasEnergyWeapon = weapons.some((weapon) => {
|
|
@@ -2012,7 +2066,7 @@ function apply(ctx, config) {
|
|
|
2012
2066
|
});
|
|
2013
2067
|
return {
|
|
2014
2068
|
success: hasEnergyWeapon,
|
|
2015
|
-
message:
|
|
2069
|
+
message: `需要至少拥有一把3级及以上等级的能量武器`
|
|
2016
2070
|
};
|
|
2017
2071
|
case "纵火狂":
|
|
2018
2072
|
const hasthermalWeapon = weapons.some((weapon) => {
|
|
@@ -2021,22 +2075,29 @@ function apply(ctx, config) {
|
|
|
2021
2075
|
});
|
|
2022
2076
|
return {
|
|
2023
2077
|
success: hasthermalWeapon,
|
|
2024
|
-
message:
|
|
2078
|
+
message: `需要至少拥有一把3级及以上等级的热能武器`
|
|
2025
2079
|
};
|
|
2080
|
+
case "猩红杀手":
|
|
2081
|
+
{
|
|
2082
|
+
const scoutRifle = weapons.find((weapon) => weapon.weaponId === 7);
|
|
2083
|
+
return {
|
|
2084
|
+
success: !!scoutRifle,
|
|
2085
|
+
message: scoutRifle ? "" : "需要“侦查步枪”武器等级≥3"
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
;
|
|
2026
2089
|
case "清洁工":
|
|
2027
2090
|
if (!mainBoss) return { success: false, message: "当前暂无伤害榜。" };
|
|
2028
|
-
const
|
|
2029
|
-
|
|
2030
|
-
}).orderBy("totalDamage", "desc").limit(3).execute();
|
|
2031
|
-
const isCleanTop3 = cleanTop3.some((r) => r.handle === handle);
|
|
2091
|
+
const cleanTop20 = await ctx2.database.select("ggcevo_boss_damage").where({ bossGroupId: mainBoss.groupId }).orderBy("totalDamage", "desc").limit(20).execute();
|
|
2092
|
+
const isInTop20 = cleanTop20.some((r) => r.handle === handle);
|
|
2032
2093
|
return {
|
|
2033
|
-
success:
|
|
2034
|
-
message: "
|
|
2094
|
+
success: isInTop20,
|
|
2095
|
+
message: "需要当期伤害榜前二十名"
|
|
2035
2096
|
};
|
|
2036
2097
|
case "辛迪加财务经理":
|
|
2037
2098
|
return {
|
|
2038
|
-
success: signData?.monthlyDays >=
|
|
2039
|
-
message: `需要当月累计签到
|
|
2099
|
+
success: signData?.monthlyDays >= 14,
|
|
2100
|
+
message: `需要当月累计签到14天及以上(当前${signData?.monthlyDays || 0}天)`
|
|
2040
2101
|
};
|
|
2041
2102
|
default:
|
|
2042
2103
|
return { success: false, message: "未知职业要求" };
|
|
@@ -2315,13 +2376,30 @@ function apply(ctx, config) {
|
|
|
2315
2376
|
].join("\n");
|
|
2316
2377
|
}
|
|
2317
2378
|
__name(generateUpgradePriceList, "generateUpgradePriceList");
|
|
2379
|
+
const weaponConfigById = {};
|
|
2380
|
+
for (const key in weaponConfig) {
|
|
2381
|
+
weaponConfigById[weaponConfig[key].id] = weaponConfig[key];
|
|
2382
|
+
}
|
|
2383
|
+
async function calculateTotalPower(handle, baseRank) {
|
|
2384
|
+
const weapons = await ctx.database.get("ggcevo_equipment", { handle });
|
|
2385
|
+
let total = baseRank;
|
|
2386
|
+
for (const { weaponId, level, installedMods } of weapons) {
|
|
2387
|
+
const weapon = weaponConfigById[weaponId];
|
|
2388
|
+
if (!weapon) continue;
|
|
2389
|
+
total += weapon.damage * 100;
|
|
2390
|
+
total += level * 1e3;
|
|
2391
|
+
total += (installedMods?.length || 0) * 2e3;
|
|
2392
|
+
}
|
|
2393
|
+
return total;
|
|
2394
|
+
}
|
|
2395
|
+
__name(calculateTotalPower, "calculateTotalPower");
|
|
2318
2396
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
2319
2397
|
const session = argv.session;
|
|
2320
2398
|
let winCount = 0;
|
|
2321
2399
|
let hiddenWinCount = 0;
|
|
2322
2400
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2323
2401
|
if (!profile) {
|
|
2324
|
-
return "
|
|
2402
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
2325
2403
|
}
|
|
2326
2404
|
const { regionId, realmId, profileId } = profile;
|
|
2327
2405
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -2360,7 +2438,7 @@ function apply(ctx, config) {
|
|
|
2360
2438
|
const session = argv.session;
|
|
2361
2439
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2362
2440
|
if (!profile) {
|
|
2363
|
-
return "
|
|
2441
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
2364
2442
|
}
|
|
2365
2443
|
const { regionId, realmId, profileId } = profile;
|
|
2366
2444
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -2393,7 +2471,7 @@ function apply(ctx, config) {
|
|
|
2393
2471
|
let hiddenWinCount = 0;
|
|
2394
2472
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2395
2473
|
if (!profile) {
|
|
2396
|
-
return "
|
|
2474
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
2397
2475
|
}
|
|
2398
2476
|
const { regionId, realmId, profileId } = profile;
|
|
2399
2477
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -2431,7 +2509,7 @@ function apply(ctx, config) {
|
|
|
2431
2509
|
const session = argv.session;
|
|
2432
2510
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2433
2511
|
if (!profile) {
|
|
2434
|
-
return "
|
|
2512
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
2435
2513
|
}
|
|
2436
2514
|
const { regionId, realmId, profileId } = profile;
|
|
2437
2515
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -2446,7 +2524,7 @@ function apply(ctx, config) {
|
|
|
2446
2524
|
ctx.command("ggcevo/背包").action(async (argv) => {
|
|
2447
2525
|
const session = argv.session;
|
|
2448
2526
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2449
|
-
if (!profile) return "
|
|
2527
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2450
2528
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2451
2529
|
const items = await ctx.database.get("ggcevo_backpack", { handle });
|
|
2452
2530
|
const validItems = items.filter((item) => item.quantity > 0);
|
|
@@ -2467,7 +2545,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2467
2545
|
const session = argv.session;
|
|
2468
2546
|
let latestTime;
|
|
2469
2547
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2470
|
-
if (!profile) return "
|
|
2548
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2471
2549
|
const { regionId, realmId, profileId } = profile;
|
|
2472
2550
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2473
2551
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -2649,7 +2727,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2649
2727
|
try {
|
|
2650
2728
|
const session = argv.session;
|
|
2651
2729
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2652
|
-
if (!profile) return "
|
|
2730
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2653
2731
|
const { regionId, realmId, profileId } = profile;
|
|
2654
2732
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2655
2733
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -2704,7 +2782,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2704
2782
|
ctx.command("ggcevo/签到记录").action(async (argv) => {
|
|
2705
2783
|
const session = argv.session;
|
|
2706
2784
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2707
|
-
if (!profile) return "
|
|
2785
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2708
2786
|
const { regionId, realmId, profileId } = profile;
|
|
2709
2787
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2710
2788
|
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
@@ -2729,7 +2807,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2729
2807
|
ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
|
|
2730
2808
|
const session = argv.session;
|
|
2731
2809
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2732
|
-
if (!profile) return "
|
|
2810
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2733
2811
|
const { regionId, realmId, profileId } = profile;
|
|
2734
2812
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2735
2813
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -2783,7 +2861,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2783
2861
|
itemIdToName[item.id] = name3;
|
|
2784
2862
|
}
|
|
2785
2863
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2786
|
-
if (!profile) return "
|
|
2864
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2787
2865
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2788
2866
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2789
2867
|
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
@@ -3184,7 +3262,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3184
3262
|
if (!player) {
|
|
3185
3263
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3186
3264
|
if (!profile) {
|
|
3187
|
-
return "
|
|
3265
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
3188
3266
|
}
|
|
3189
3267
|
const { regionId, realmId, profileId } = profile;
|
|
3190
3268
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -3300,7 +3378,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3300
3378
|
let handle;
|
|
3301
3379
|
if (!user) {
|
|
3302
3380
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3303
|
-
if (!profile) return "
|
|
3381
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3304
3382
|
handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3305
3383
|
} else {
|
|
3306
3384
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
@@ -3349,7 +3427,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3349
3427
|
ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
|
|
3350
3428
|
try {
|
|
3351
3429
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3352
|
-
if (!profile) return "
|
|
3430
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3353
3431
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3354
3432
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3355
3433
|
if (existingEntries.length > 0) {
|
|
@@ -3465,7 +3543,7 @@ ${items.join("、")}
|
|
|
3465
3543
|
});
|
|
3466
3544
|
ctx.command("ggcevo/兑换记录").action(async ({ session }) => {
|
|
3467
3545
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3468
|
-
if (!profile) return "
|
|
3546
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3469
3547
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3470
3548
|
const exchanges = await ctx.database.get("ggcevo_exchange", { handle });
|
|
3471
3549
|
if (!exchanges.length) return "您暂无兑换记录";
|
|
@@ -3484,7 +3562,7 @@ ${output}`;
|
|
|
3484
3562
|
});
|
|
3485
3563
|
ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
|
|
3486
3564
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3487
|
-
if (!profile) return "
|
|
3565
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3488
3566
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3489
3567
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3490
3568
|
if (existingEntries.length > 0) {
|
|
@@ -3514,7 +3592,7 @@ ${output}`;
|
|
|
3514
3592
|
const session = argv.session;
|
|
3515
3593
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3516
3594
|
if (!profile) {
|
|
3517
|
-
return "
|
|
3595
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
3518
3596
|
}
|
|
3519
3597
|
const { regionId, realmId, profileId } = profile;
|
|
3520
3598
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -3606,7 +3684,7 @@ ${output}`;
|
|
|
3606
3684
|
ctx.command("ggcevo/成就").action(async ({ session }) => {
|
|
3607
3685
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3608
3686
|
if (!profile) {
|
|
3609
|
-
return "
|
|
3687
|
+
return "🔒 需要先绑定游戏句柄。";
|
|
3610
3688
|
}
|
|
3611
3689
|
const { regionId, realmId, profileId } = profile;
|
|
3612
3690
|
const achievements = await ctx.database.get("ggcevo_achievements", {
|
|
@@ -3631,7 +3709,7 @@ ${achievementList.join("\n")}`;
|
|
|
3631
3709
|
const session = argv.session;
|
|
3632
3710
|
const output = [];
|
|
3633
3711
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3634
|
-
if (!profile) return "
|
|
3712
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3635
3713
|
const { regionId, realmId, profileId } = profile;
|
|
3636
3714
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
3637
3715
|
output.push(`🎮 游戏句柄:${handle}
|
|
@@ -3763,9 +3841,9 @@ ${achievementList.join("\n")}`;
|
|
|
3763
3841
|
ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
|
|
3764
3842
|
try {
|
|
3765
3843
|
const session = argv.session;
|
|
3766
|
-
if (!user) return "
|
|
3844
|
+
if (!user) return "请输入“pk @指定pk玩家”。";
|
|
3767
3845
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3768
|
-
if (!profile) return "
|
|
3846
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3769
3847
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3770
3848
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3771
3849
|
if (existingEntries.length > 0) {
|
|
@@ -3786,6 +3864,8 @@ ${achievementList.join("\n")}`;
|
|
|
3786
3864
|
]);
|
|
3787
3865
|
const initiatorRank = initiatorData[0]?.rank || 0;
|
|
3788
3866
|
const targetRank = targetData[0]?.rank || 0;
|
|
3867
|
+
const initiatorPower = await calculateTotalPower(initiatorHandle, initiatorRank);
|
|
3868
|
+
const targetPower = await calculateTotalPower(targetHandle, targetRank);
|
|
3789
3869
|
const initiatorRankname = initiatorData[0]?.name || session.username;
|
|
3790
3870
|
const targetRankname = targetData[0]?.name || (targetUsername.name || targetUsername.user.name);
|
|
3791
3871
|
let initiatorPK = {
|
|
@@ -3863,9 +3943,9 @@ ${achievementList.join("\n")}`;
|
|
|
3863
3943
|
const targetGold = targetSign[0]?.totalRewards || 0;
|
|
3864
3944
|
if (initiatorGold < 100) return "发起者需要至少100金币才能发起挑战。";
|
|
3865
3945
|
if (targetGold < 100) return "对方金币不足100,无法应战。";
|
|
3866
|
-
const
|
|
3867
|
-
|
|
3868
|
-
|
|
3946
|
+
const powerDiff = initiatorPower - targetPower;
|
|
3947
|
+
let winRate = 50 + powerDiff / 20 * 0.01;
|
|
3948
|
+
winRate = Math.min(Math.max(winRate, 5), 95);
|
|
3869
3949
|
const isWin = Math.random() * 100 < winRate;
|
|
3870
3950
|
const stealPercentage = getRandomInt(1, 5);
|
|
3871
3951
|
const goldTransfer = Math.floor(
|
|
@@ -3933,13 +4013,13 @@ ${achievementList.join("\n")}`;
|
|
|
3933
4013
|
});
|
|
3934
4014
|
const result = [
|
|
3935
4015
|
`⚔️【对战结果】${isWin ? "胜利" : "失败"}`,
|
|
3936
|
-
`🏅 挑战者:${initiatorRankname}(
|
|
3937
|
-
`🛡️ 应战者:${targetRankname}(
|
|
4016
|
+
`🏅 挑战者:${initiatorRankname}(战斗力 ${initiatorRank})`,
|
|
4017
|
+
`🛡️ 应战者:${targetRankname}(战斗力 ${targetRank})`,
|
|
3938
4018
|
`📊 胜率预测:${winRate.toFixed(1)}%`,
|
|
3939
4019
|
`🎰 金币变动:${stealPercentage}%`
|
|
3940
4020
|
];
|
|
3941
4021
|
isWin ? result.push(`💰 您从对方的口袋里抢夺了${goldTransfer}枚金币`) : result.push(`💸 您从口袋里拿出了${goldTransfer}枚金币上交给对方`);
|
|
3942
|
-
initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 海盗阵营奖励:获得1
|
|
4022
|
+
initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 海盗阵营奖励:获得1枚红晶`) : "";
|
|
3943
4023
|
result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
|
|
3944
4024
|
return result.join("\n");
|
|
3945
4025
|
} catch (error) {
|
|
@@ -3980,7 +4060,7 @@ ${achievementList.join("\n")}`;
|
|
|
3980
4060
|
});
|
|
3981
4061
|
ctx.command("ggcevo/切换pk", "切换玩家对战状态").alias("切换pk状态").action(async ({ session }) => {
|
|
3982
4062
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3983
|
-
if (!profile) return "
|
|
4063
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3984
4064
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3985
4065
|
const [pkRecord] = await ctx.database.get("ggcevo_pk", { handle }) || [null];
|
|
3986
4066
|
const currentState = pkRecord?.enable ?? true;
|
|
@@ -4073,7 +4153,7 @@ ${Object.keys(typeStats).join("、")}`;
|
|
|
4073
4153
|
});
|
|
4074
4154
|
return [
|
|
4075
4155
|
`🏪 咕咕武器库 - ${type} 🏪`,
|
|
4076
|
-
"使用“购买
|
|
4156
|
+
"使用“购买 武器名称”指令进行购买",
|
|
4077
4157
|
discountRate > 0 && `🔧 当前购买折扣:${discountRate}% (武器系统 Lv${techLevel})`,
|
|
4078
4158
|
"====================",
|
|
4079
4159
|
...items,
|
|
@@ -4114,7 +4194,7 @@ ${validTypes.join("、")}`;
|
|
|
4114
4194
|
].join("\n"));
|
|
4115
4195
|
return [
|
|
4116
4196
|
`💣 爆破装备库 - ${type} 💣`,
|
|
4117
|
-
"使用“购买
|
|
4197
|
+
"使用“购买 物品名称”指令进行购买",
|
|
4118
4198
|
"====================",
|
|
4119
4199
|
...items,
|
|
4120
4200
|
items.length === 0 ? "⚠️ 该分类下暂无可用物品" : ""
|
|
@@ -4122,7 +4202,7 @@ ${validTypes.join("、")}`;
|
|
|
4122
4202
|
});
|
|
4123
4203
|
ctx.command("ggcevo/购买 <item>").action(async ({ session }, item) => {
|
|
4124
4204
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4125
|
-
if (!profile) return "
|
|
4205
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4126
4206
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4127
4207
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4128
4208
|
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
@@ -4248,7 +4328,7 @@ ${validTypes.join("、")}`;
|
|
|
4248
4328
|
});
|
|
4249
4329
|
ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
|
|
4250
4330
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4251
|
-
if (!profile) return "
|
|
4331
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4252
4332
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4253
4333
|
const weapons = await ctx.database.get("ggcevo_equipment", {
|
|
4254
4334
|
handle
|
|
@@ -4268,7 +4348,7 @@ ${validTypes.join("、")}`;
|
|
|
4268
4348
|
].join("\n");
|
|
4269
4349
|
}));
|
|
4270
4350
|
return [
|
|
4271
|
-
|
|
4351
|
+
`🛡️ ${handle}当前拥有的武器`,
|
|
4272
4352
|
'使用"装备 武器名称"来装备武器',
|
|
4273
4353
|
"⚡表示当前装备武器",
|
|
4274
4354
|
"──────────────",
|
|
@@ -4280,7 +4360,7 @@ ${validTypes.join("、")}`;
|
|
|
4280
4360
|
});
|
|
4281
4361
|
ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
|
|
4282
4362
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4283
|
-
if (!profile) return "
|
|
4363
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4284
4364
|
if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4285
4365
|
if (!weaponConfig[weapon]) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4286
4366
|
const config2 = weaponConfig[weapon];
|
|
@@ -4314,7 +4394,7 @@ ${validTypes.join("、")}`;
|
|
|
4314
4394
|
});
|
|
4315
4395
|
ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
|
|
4316
4396
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4317
|
-
if (!profile) return "
|
|
4397
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4318
4398
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4319
4399
|
if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
|
|
4320
4400
|
return "❌ 拒绝访问,您已被列入黑名单";
|
|
@@ -4335,7 +4415,7 @@ ${validTypes.join("、")}`;
|
|
|
4335
4415
|
});
|
|
4336
4416
|
ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
|
|
4337
4417
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4338
|
-
if (!profile) return "
|
|
4418
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4339
4419
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4340
4420
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4341
4421
|
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单";
|
|
@@ -4428,7 +4508,7 @@ ${validTypes.join("、")}`;
|
|
|
4428
4508
|
exclusiveDiscountRate > 0 && `🔧 当前专属模块折扣:${exclusiveDiscountRate}% (武器升级平台 Lv${techLevel})`,
|
|
4429
4509
|
"====================",
|
|
4430
4510
|
exclusiveMods.length ? exclusiveMods.join("\n\n") : "该武器暂无专属模块"
|
|
4431
|
-
].join("\n\n");
|
|
4511
|
+
].filter(Boolean).join("\n\n");
|
|
4432
4512
|
} else {
|
|
4433
4513
|
const universalMods = Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(([name2, cfg]) => formatMod(name2, cfg));
|
|
4434
4514
|
return [
|
|
@@ -4437,7 +4517,7 @@ ${validTypes.join("、")}`;
|
|
|
4437
4517
|
universalDiscountRate > 0 && `🔧 当前通用模块折扣:${universalDiscountRate}% (武器升级平台 Lv${techLevel})`,
|
|
4438
4518
|
"====================",
|
|
4439
4519
|
universalMods.join("\n\n")
|
|
4440
|
-
].join("\n\n");
|
|
4520
|
+
].filter(Boolean).join("\n\n");
|
|
4441
4521
|
}
|
|
4442
4522
|
}, "showModList");
|
|
4443
4523
|
if (mod) {
|
|
@@ -4449,6 +4529,11 @@ ${validTypes.join("、")}`;
|
|
|
4449
4529
|
ctx.command("ggcevo/攻击 <bossName>").usage("请输入要攻击的异形名称(例如:攻击 异齿猛兽 或 攻击 寒冰王蛇)").action(async (argv, bossName) => {
|
|
4450
4530
|
const session = argv.session;
|
|
4451
4531
|
let broadcastMessage = null;
|
|
4532
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4533
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4534
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4535
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4536
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
4452
4537
|
const getActiveBossNames = /* @__PURE__ */ __name(async () => {
|
|
4453
4538
|
const activeBosses2 = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4454
4539
|
return activeBosses2.map((b) => b.name).join(",");
|
|
@@ -4467,11 +4552,6 @@ ${validTypes.join("、")}`;
|
|
|
4467
4552
|
return `当前没有找到名为 ${bossName} 的可攻击目标。
|
|
4468
4553
|
请攻击当前存活的异形:${activeNames || "无"}。`;
|
|
4469
4554
|
}
|
|
4470
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4471
|
-
if (!profile) return "您暂未绑定句柄。";
|
|
4472
|
-
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4473
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4474
|
-
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
4475
4555
|
const config2 = ctx.config;
|
|
4476
4556
|
const unlimitedBossAttack = config2.unlimitedBossAttack;
|
|
4477
4557
|
if (!unlimitedBossAttack) {
|
|
@@ -4494,17 +4574,17 @@ ${validTypes.join("、")}`;
|
|
|
4494
4574
|
if (!weaponData.isantiair && targetBoss.groupId === 5) {
|
|
4495
4575
|
return "您装备的武器无法攻击空中目标!";
|
|
4496
4576
|
}
|
|
4497
|
-
const { damage: baseDamage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
4498
4577
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4499
|
-
if (!activeBosses.length) return "
|
|
4578
|
+
if (!activeBosses.length) return "当前没有存活的异形,请等待下一轮刷新。";
|
|
4500
4579
|
const bossGroup = bossPool.find(
|
|
4501
4580
|
(g) => g.main.name === targetBoss.name || g.minions.some((m) => m.name === targetBoss.name)
|
|
4502
4581
|
);
|
|
4503
4582
|
if (!bossGroup) return "无法获取异形组配置。";
|
|
4504
4583
|
const maxHP = targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions.find((m) => m.name === targetBoss.name)?.maxHP || 0;
|
|
4505
|
-
|
|
4584
|
+
const { damage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
4585
|
+
let initialDamage = Math.min(damage, targetBoss.HP);
|
|
4506
4586
|
let currentHP = targetBoss.HP - initialDamage;
|
|
4507
|
-
let
|
|
4587
|
+
let passiveMessages = [];
|
|
4508
4588
|
const passiveResult = await PassiveHandler.handlePassives(
|
|
4509
4589
|
ctx,
|
|
4510
4590
|
targetBoss,
|
|
@@ -4513,13 +4593,12 @@ ${validTypes.join("、")}`;
|
|
|
4513
4593
|
maxHP,
|
|
4514
4594
|
weaponName,
|
|
4515
4595
|
weaponData,
|
|
4516
|
-
baseDamage,
|
|
4517
4596
|
activeBosses,
|
|
4518
4597
|
bossGroup
|
|
4519
4598
|
);
|
|
4520
4599
|
currentHP = passiveResult.currentHP;
|
|
4521
4600
|
initialDamage = passiveResult.initialDamage;
|
|
4522
|
-
|
|
4601
|
+
passiveMessages.push(...passiveResult.messages);
|
|
4523
4602
|
if (passiveResult.skillUpdates.length > 0) {
|
|
4524
4603
|
await PassiveHandler.applySkillUpdates(ctx, passiveResult.skillUpdates);
|
|
4525
4604
|
}
|
|
@@ -4587,7 +4666,7 @@ ${validTypes.join("、")}`;
|
|
|
4587
4666
|
await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
|
|
4588
4667
|
skills: [...mainBoss.skills, "孤立无援"]
|
|
4589
4668
|
});
|
|
4590
|
-
broadcastMessages.push("💥
|
|
4669
|
+
broadcastMessages.push("💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!");
|
|
4591
4670
|
}
|
|
4592
4671
|
} else {
|
|
4593
4672
|
remainingMinions = await ctx.database.get("ggcevo_boss", {
|
|
@@ -4605,7 +4684,7 @@ ${validTypes.join("、")}`;
|
|
|
4605
4684
|
await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
|
|
4606
4685
|
skills: [...mainBoss.skills, "孤立无援"]
|
|
4607
4686
|
});
|
|
4608
|
-
broadcastMessages.push(
|
|
4687
|
+
broadcastMessages.push(`💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`);
|
|
4609
4688
|
}
|
|
4610
4689
|
}
|
|
4611
4690
|
}
|
|
@@ -4637,7 +4716,7 @@ ${validTypes.join("、")}`;
|
|
|
4637
4716
|
handle,
|
|
4638
4717
|
redcrystal: (careerData?.redcrystal || 0) + 1
|
|
4639
4718
|
}], ["handle"]);
|
|
4640
|
-
redcrystalMessage = "🔴 清洁工职业加成:获得1
|
|
4719
|
+
redcrystalMessage = "🔴 清洁工职业加成:获得1枚红晶";
|
|
4641
4720
|
}
|
|
4642
4721
|
const finalReward = Math.round(initialDamage * careerMultiplier);
|
|
4643
4722
|
const [existingSign] = await ctx.database.get("ggcevo_sign", { handle });
|
|
@@ -4649,12 +4728,15 @@ ${validTypes.join("、")}`;
|
|
|
4649
4728
|
const resultMessage = [
|
|
4650
4729
|
`🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
|
|
4651
4730
|
...effectMessage.length > 0 ? [
|
|
4652
|
-
|
|
4653
|
-
${effectMessage.join("\n")}`
|
|
4731
|
+
`⚡ 攻击效果:
|
|
4732
|
+
${effectMessage.map((m) => `▸ ${m}`).join("\n")}`
|
|
4733
|
+
] : [],
|
|
4734
|
+
// === 新增被动效果提示区域 ===
|
|
4735
|
+
...passiveMessages.length > 0 ? [
|
|
4736
|
+
`🛡️ 被动效果:
|
|
4737
|
+
${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
4654
4738
|
] : [],
|
|
4655
|
-
...healMessages,
|
|
4656
4739
|
`造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
|
|
4657
|
-
// 修改金币显示行
|
|
4658
4740
|
`获得金币:${finalReward}${careerMessage}`,
|
|
4659
4741
|
redcrystalMessage,
|
|
4660
4742
|
`目标剩余HP:${Math.max(currentHP, 0)}/${maxHP}`,
|
|
@@ -4667,14 +4749,13 @@ ${effectMessage.join("\n")}`
|
|
|
4667
4749
|
await ctx.broadcast(groupId, finalBroadcast);
|
|
4668
4750
|
}
|
|
4669
4751
|
});
|
|
4670
|
-
ctx.command("ggcevo/攻击假人").
|
|
4752
|
+
ctx.command("ggcevo/攻击假人").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").action(async (argv) => {
|
|
4671
4753
|
const session = argv.session;
|
|
4672
4754
|
const { options } = argv;
|
|
4673
4755
|
const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
|
|
4674
4756
|
const tags = parseList(options.tags);
|
|
4675
|
-
const passives = parseList(options.passives);
|
|
4676
4757
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4677
|
-
if (!profile) return "
|
|
4758
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4678
4759
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4679
4760
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4680
4761
|
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
@@ -4688,8 +4769,6 @@ ${effectMessage.join("\n")}`
|
|
|
4688
4769
|
HP: Infinity,
|
|
4689
4770
|
type: "主宰",
|
|
4690
4771
|
groupId: 0,
|
|
4691
|
-
skills: passives || [],
|
|
4692
|
-
// 从选项获取被动
|
|
4693
4772
|
tags: tags || []
|
|
4694
4773
|
// 从选项获取标签
|
|
4695
4774
|
};
|
|
@@ -4701,21 +4780,22 @@ ${effectMessage.join("\n")}`
|
|
|
4701
4780
|
{
|
|
4702
4781
|
isTest: true,
|
|
4703
4782
|
// 标记为测试模式
|
|
4704
|
-
customTags: tags
|
|
4705
|
-
customPassives: passives
|
|
4783
|
+
customTags: tags
|
|
4706
4784
|
}
|
|
4707
4785
|
);
|
|
4708
4786
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
4709
4787
|
const [weaponName] = weaponConfigEntry;
|
|
4710
4788
|
return [
|
|
4711
|
-
`🎯
|
|
4789
|
+
`🎯 攻击 ${dummyBoss.name}`,
|
|
4712
4790
|
`💥 使用武器:${weaponName}`,
|
|
4713
4791
|
options.tags?.length && `🏷️ 模拟标签:${tags.join(", ")}`,
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4792
|
+
...effectMessage.length ? [
|
|
4793
|
+
"⚡ 攻击效果:",
|
|
4794
|
+
...effectMessage.map((m) => `▸ ${m}`)
|
|
4795
|
+
// 这里添加符号
|
|
4796
|
+
] : [],
|
|
4797
|
+
`📊 理论伤害值:${damage}${hasCrit ? " (✨ 触发暴击)" : ""}`,
|
|
4798
|
+
"💡 提示:使用 -t 重甲,生物…… 添加测试标签"
|
|
4719
4799
|
].filter((line) => line).join("\n");
|
|
4720
4800
|
});
|
|
4721
4801
|
ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
@@ -4815,7 +4895,7 @@ ${effectMessage.join("\n")}`
|
|
|
4815
4895
|
ctx.command("ggcevo/祈愿").action(async (argv) => {
|
|
4816
4896
|
const session = argv.session;
|
|
4817
4897
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4818
|
-
if (!profile) return "
|
|
4898
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4819
4899
|
const { regionId, realmId, profileId } = profile;
|
|
4820
4900
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
4821
4901
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -4892,7 +4972,7 @@ ${effectMessage.join("\n")}`
|
|
|
4892
4972
|
});
|
|
4893
4973
|
ctx.command("兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
|
|
4894
4974
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4895
|
-
if (!profile) return "
|
|
4975
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4896
4976
|
const { regionId, realmId, profileId } = profile;
|
|
4897
4977
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
4898
4978
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -4931,7 +5011,7 @@ ${effectMessage.join("\n")}`
|
|
|
4931
5011
|
});
|
|
4932
5012
|
ctx.command("兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
|
|
4933
5013
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4934
|
-
if (!profile) return "
|
|
5014
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4935
5015
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4936
5016
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4937
5017
|
if (existingEntries.length > 0) {
|
|
@@ -4971,7 +5051,7 @@ ${effectMessage.join("\n")}`
|
|
|
4971
5051
|
});
|
|
4972
5052
|
ctx.command("ggcevo/加入 <faction>", "加入阵营").alias("加入阵营").action(async ({ session }, faction) => {
|
|
4973
5053
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4974
|
-
if (!profile) return "
|
|
5054
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
4975
5055
|
const { regionId, realmId, profileId } = profile;
|
|
4976
5056
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
4977
5057
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
@@ -5040,7 +5120,7 @@ ${effectMessage.join("\n")}`
|
|
|
5040
5120
|
});
|
|
5041
5121
|
ctx.command("ggcevo/转职 [profession]", "转职系统").action(async ({ session }, profession) => {
|
|
5042
5122
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5043
|
-
if (!profile) return "
|
|
5123
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5044
5124
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5045
5125
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
5046
5126
|
if (existingEntries.length > 0) {
|
|
@@ -5125,7 +5205,7 @@ ${effectMessage.join("\n")}`
|
|
|
5125
5205
|
const [profile] = await ctx.database.get("sc2arcade_player", {
|
|
5126
5206
|
userId: session.userId
|
|
5127
5207
|
});
|
|
5128
|
-
if (!profile) return "
|
|
5208
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5129
5209
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5130
5210
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5131
5211
|
if (!careerData) return "您尚未加入任何阵营。";
|
|
@@ -5150,9 +5230,9 @@ ${effectMessage.join("\n")}`
|
|
|
5150
5230
|
infoCard.push("", "〓 科技研发 〓", ...activeTechs);
|
|
5151
5231
|
}
|
|
5152
5232
|
}
|
|
5153
|
-
const promptMessage = careerData.group === "辛迪加海盗" ? "💡 提示:红晶可通过主动PK获得(无论胜负)" : "💡
|
|
5233
|
+
const promptMessage = careerData.group === "辛迪加海盗" ? "💡 提示:红晶可通过主动PK获得(无论胜负)" : "💡 提示:使用「转职」指令可变更职业";
|
|
5154
5234
|
return [
|
|
5155
|
-
|
|
5235
|
+
`〓 ${handle}的职业档案 〓`,
|
|
5156
5236
|
...infoCard,
|
|
5157
5237
|
"〓═════════〓\n" + promptMessage
|
|
5158
5238
|
// 提示信息放在分隔线下方
|
|
@@ -5164,7 +5244,7 @@ ${effectMessage.join("\n")}`
|
|
|
5164
5244
|
});
|
|
5165
5245
|
ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
|
|
5166
5246
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5167
|
-
if (!profile) return "
|
|
5247
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5168
5248
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5169
5249
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5170
5250
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
@@ -5233,7 +5313,7 @@ ${effectMessage.join("\n")}`
|
|
|
5233
5313
|
});
|
|
5234
5314
|
ctx.command("ggcevo/订购 <item>").action(async ({ session }, item) => {
|
|
5235
5315
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5236
|
-
if (!profile) return "
|
|
5316
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5237
5317
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5238
5318
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5239
5319
|
return "❌ 拒绝访问,您已被列入黑名单";
|
|
@@ -5319,7 +5399,7 @@ ${effectMessage.join("\n")}`
|
|
|
5319
5399
|
ctx.command("ggcevo/仓库").action(async (argv) => {
|
|
5320
5400
|
const session = argv.session;
|
|
5321
5401
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5322
|
-
if (!profile) return "
|
|
5402
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5323
5403
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5324
5404
|
const [items, signData, careerData] = await Promise.all([
|
|
5325
5405
|
ctx.database.get("ggcevo_warehouse", { handle }),
|
|
@@ -5362,7 +5442,7 @@ ${effectMessage.join("\n")}`
|
|
|
5362
5442
|
ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
|
|
5363
5443
|
const session = argv.session;
|
|
5364
5444
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5365
|
-
if (!profile) return "🔒
|
|
5445
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5366
5446
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5367
5447
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5368
5448
|
return "⛔ 您已被列入黑名单";
|
|
@@ -5402,7 +5482,7 @@ ${effectMessage.join("\n")}`
|
|
|
5402
5482
|
});
|
|
5403
5483
|
ctx.command("ggcevo/科技 [techName]", "查看空间站科技信息").usage("输入“科技”查看列表,或“科技 科技名称”查看详细信息").action(async ({ session }, techName) => {
|
|
5404
5484
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5405
|
-
if (!profile) return "🔒
|
|
5485
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5406
5486
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5407
5487
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5408
5488
|
if (!careerData || careerData.group !== "人类联盟") {
|
|
@@ -5450,7 +5530,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5450
5530
|
return new Date(utcDate.getTime() + chinaOffset);
|
|
5451
5531
|
}, "convertUTCtoChinaTime");
|
|
5452
5532
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5453
|
-
if (!profile) return "🔒
|
|
5533
|
+
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
5454
5534
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5455
5535
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5456
5536
|
return "⛔ 您已被列入黑名单";
|
|
@@ -5472,7 +5552,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5472
5552
|
startTime: /* @__PURE__ */ new Date()
|
|
5473
5553
|
// 记录当前时间为开始时间
|
|
5474
5554
|
});
|
|
5475
|
-
return "⛏️ 挖矿作业已开始,至少1
|
|
5555
|
+
return "⛏️ 挖矿作业已开始,至少1小时后可收获。";
|
|
5476
5556
|
}
|
|
5477
5557
|
const nowtime = /* @__PURE__ */ new Date();
|
|
5478
5558
|
const chinaStart = convertUTCtoChinaTime2(record.startTime);
|
|
@@ -5525,7 +5605,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5525
5605
|
`🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5526
5606
|
`⏱️ 结束时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5527
5607
|
`⏳ 持续时间:${formatTime(duration)}`,
|
|
5528
|
-
...tech.level >=
|
|
5608
|
+
...tech.level >= 4 ? (
|
|
5529
5609
|
// 仅当科技等级≥3时显示加成信息
|
|
5530
5610
|
[`🔧 科技加成(Lv.${tech.level}):+${multiplier * 100}%`]
|
|
5531
5611
|
) : [],
|