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