koishi-plugin-ggcevo-game 1.2.19 → 1.2.21
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.d.ts +9 -0
- package/lib/index.js +341 -45
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ declare module 'koishi' {
|
|
|
38
38
|
ggcevo_equipment: equipment;
|
|
39
39
|
ggcevo_boss: Boss;
|
|
40
40
|
ggcevo_boss_damage: BossDamageRecord;
|
|
41
|
+
ggcevo_Wish_Record: WishRecord;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
export interface backpack {
|
|
@@ -156,4 +157,12 @@ export interface BossDamageRecord {
|
|
|
156
157
|
bossGroupId: number;
|
|
157
158
|
lastattackDate: Date;
|
|
158
159
|
}
|
|
160
|
+
export interface WishRecord {
|
|
161
|
+
id: number;
|
|
162
|
+
handle: string;
|
|
163
|
+
wishname: string;
|
|
164
|
+
startTime: Date;
|
|
165
|
+
endTime: Date;
|
|
166
|
+
isused: boolean;
|
|
167
|
+
}
|
|
159
168
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -245,6 +245,17 @@ function apply(ctx, config) {
|
|
|
245
245
|
}, {
|
|
246
246
|
primary: "handle"
|
|
247
247
|
});
|
|
248
|
+
ctx.model.extend("ggcevo_Wish_Record", {
|
|
249
|
+
id: "unsigned",
|
|
250
|
+
handle: "string",
|
|
251
|
+
wishname: "string",
|
|
252
|
+
startTime: "timestamp",
|
|
253
|
+
endTime: "timestamp",
|
|
254
|
+
isused: "boolean"
|
|
255
|
+
}, {
|
|
256
|
+
primary: "id",
|
|
257
|
+
autoInc: true
|
|
258
|
+
});
|
|
248
259
|
const weaponConfig = {
|
|
249
260
|
// 武器配置
|
|
250
261
|
"高斯步枪": {
|
|
@@ -338,6 +349,55 @@ function apply(ctx, config) {
|
|
|
338
349
|
isExclusive: true
|
|
339
350
|
}
|
|
340
351
|
};
|
|
352
|
+
const wishConfig = {
|
|
353
|
+
// 普通祈愿(总概率 5 * 19=95%)
|
|
354
|
+
common: [
|
|
355
|
+
{
|
|
356
|
+
name: "蚱蜢优购",
|
|
357
|
+
effect: "下一次购买武器价格变为80%"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: "灵狐升运",
|
|
361
|
+
effect: "下一次升级武器价格变为80%"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: "王权增幅",
|
|
365
|
+
type: "buff",
|
|
366
|
+
effect: "攻击伤害+10%"
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
name: "金柚赐福",
|
|
370
|
+
effect: "立即获得250枚金币"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
name: "夜市赠礼",
|
|
374
|
+
effect: "立即获得5枚咕咕币"
|
|
375
|
+
}
|
|
376
|
+
],
|
|
377
|
+
// 稀有祈愿(总概率 5 * 1=5%)
|
|
378
|
+
rare: [
|
|
379
|
+
{
|
|
380
|
+
name: "悲鸣之锋",
|
|
381
|
+
effect: "基于武器等级的伤害加成(0级为10%,每等级增加10%)"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: "精灵双倍",
|
|
385
|
+
effect: "下一次击败首领时获得双倍奖励"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: "喵喵财源",
|
|
389
|
+
effect: "签到奖励翻倍"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
name: "暴击韵律",
|
|
393
|
+
effect: "攻击时,暴击率+20%"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "酥手空空",
|
|
397
|
+
effect: "失去50枚金币"
|
|
398
|
+
}
|
|
399
|
+
]
|
|
400
|
+
};
|
|
341
401
|
const passiveConfig = {
|
|
342
402
|
"弱化形态": {
|
|
343
403
|
effect: 0.1,
|
|
@@ -375,7 +435,7 @@ function apply(ctx, config) {
|
|
|
375
435
|
]
|
|
376
436
|
}
|
|
377
437
|
];
|
|
378
|
-
function calculateModifiers(equippedWeapon, weaponName) {
|
|
438
|
+
function calculateModifiers(equippedWeapon, weaponName, hasCritRhythm) {
|
|
379
439
|
let totalModAdd = 0;
|
|
380
440
|
let hasCrit = false;
|
|
381
441
|
let hasCrystal = false;
|
|
@@ -392,7 +452,10 @@ function apply(ctx, config) {
|
|
|
392
452
|
hasOverload = true;
|
|
393
453
|
}
|
|
394
454
|
});
|
|
395
|
-
|
|
455
|
+
let totalCritRate = (hasCrystal ? 20 : 0) + (hasOverload ? 80 : 0);
|
|
456
|
+
if (hasCritRhythm) {
|
|
457
|
+
totalCritRate = Math.min(totalCritRate + 20, 100);
|
|
458
|
+
}
|
|
396
459
|
if (totalCritRate > 0 && Math.random() < totalCritRate / 100) {
|
|
397
460
|
hasCrit = true;
|
|
398
461
|
totalModAdd += 1;
|
|
@@ -444,11 +507,28 @@ function apply(ctx, config) {
|
|
|
444
507
|
}
|
|
445
508
|
__name(calculateRankBonus, "calculateRankBonus");
|
|
446
509
|
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss) {
|
|
510
|
+
let effectMessage = [];
|
|
511
|
+
const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
|
|
512
|
+
const { regionId, realmId, profileId } = profile;
|
|
513
|
+
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
447
514
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
448
515
|
const [weaponName, weaponData] = weaponConfigEntry;
|
|
449
516
|
let damage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
|
|
450
|
-
const
|
|
517
|
+
const [critRhythmEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
|
|
518
|
+
handle,
|
|
519
|
+
wishname: "暴击韵律",
|
|
520
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
521
|
+
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
522
|
+
});
|
|
523
|
+
const { totalModAdd, hasCrit } = calculateModifiers(
|
|
524
|
+
equippedWeapon,
|
|
525
|
+
weaponName,
|
|
526
|
+
!!critRhythmEffect
|
|
527
|
+
);
|
|
451
528
|
damage *= 1 + totalModAdd;
|
|
529
|
+
if (critRhythmEffect) {
|
|
530
|
+
effectMessage.push("🎵 暴击韵律生效(暴击率+20%)");
|
|
531
|
+
}
|
|
452
532
|
const targetBossConfig = targetBoss.type === "主宰" ? bossPool.find((g) => g.main.name === targetBoss.name).main : bossPool.find((g) => g.minions.some((m) => m.name === targetBoss.name)).minions[0];
|
|
453
533
|
const tagMultiplier = calculateTagEffects(weaponData, targetBossConfig, equippedWeapon);
|
|
454
534
|
damage *= 1 + tagMultiplier;
|
|
@@ -459,10 +539,35 @@ function apply(ctx, config) {
|
|
|
459
539
|
});
|
|
460
540
|
const passiveMultiplier = calculatePassiveEffects(targetBossConfig, activeMinions.length);
|
|
461
541
|
damage *= 1 + passiveMultiplier;
|
|
542
|
+
const [sovereignEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
|
|
543
|
+
handle,
|
|
544
|
+
wishname: "王权增幅",
|
|
545
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
546
|
+
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
547
|
+
});
|
|
548
|
+
const [lamentEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
|
|
549
|
+
handle,
|
|
550
|
+
wishname: "悲鸣之锋",
|
|
551
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
552
|
+
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
553
|
+
});
|
|
554
|
+
if (sovereignEffect) {
|
|
555
|
+
damage *= 1.1;
|
|
556
|
+
effectMessage.push(`👑 王权增幅生效(攻击伤害+10%)`);
|
|
557
|
+
}
|
|
558
|
+
if (lamentEffect) {
|
|
559
|
+
const levelBonus = 0.1 * (equippedWeapon.level + 1);
|
|
560
|
+
damage *= 1 + levelBonus;
|
|
561
|
+
effectMessage.push(`🗡️ 悲鸣之锋触发(+${(levelBonus * 100).toFixed(0)}%等级加成)`);
|
|
562
|
+
}
|
|
462
563
|
const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle: session.handle });
|
|
463
564
|
const rankBonus = calculateRankBonus(rankRecord);
|
|
464
565
|
damage *= 1 + rankBonus;
|
|
465
|
-
return {
|
|
566
|
+
return {
|
|
567
|
+
damage: Math.round(damage),
|
|
568
|
+
hasCrit,
|
|
569
|
+
effectMessage
|
|
570
|
+
};
|
|
466
571
|
}
|
|
467
572
|
__name(calculateTotalDamage, "calculateTotalDamage");
|
|
468
573
|
const initDefaultItems = {
|
|
@@ -614,12 +719,6 @@ function apply(ctx, config) {
|
|
|
614
719
|
return mainBoss;
|
|
615
720
|
}
|
|
616
721
|
__name(activateNextBossGroup, "activateNextBossGroup");
|
|
617
|
-
function createHpBar(current, max) {
|
|
618
|
-
const ratio = current / max;
|
|
619
|
-
const filled = Math.floor(ratio * 20);
|
|
620
|
-
return "▰".repeat(filled) + "▱".repeat(20 - filled);
|
|
621
|
-
}
|
|
622
|
-
__name(createHpBar, "createHpBar");
|
|
623
722
|
ctx.setInterval(async () => {
|
|
624
723
|
const now = /* @__PURE__ */ new Date();
|
|
625
724
|
const expiredGroups = await ctx.database.select("ggcevo_boss").where({
|
|
@@ -835,8 +934,16 @@ ${itemDetails.join("\n")}`;
|
|
|
835
934
|
monthlyDays = record.monthlyDays + 1;
|
|
836
935
|
}
|
|
837
936
|
}
|
|
937
|
+
const [meowEffect] = await ctx.database.get("ggcevo_Wish_Record", {
|
|
938
|
+
handle,
|
|
939
|
+
wishname: "喵喵财源",
|
|
940
|
+
startTime: { $lte: now },
|
|
941
|
+
endTime: { $gte: now },
|
|
942
|
+
isused: false
|
|
943
|
+
});
|
|
838
944
|
let tickets = 3;
|
|
839
945
|
let points = getRandomInt(20, 40);
|
|
946
|
+
let effectMessage = "";
|
|
840
947
|
if (monthlyDays === 7) {
|
|
841
948
|
tickets = 4;
|
|
842
949
|
} else if (monthlyDays === 14) {
|
|
@@ -855,6 +962,11 @@ ${itemDetails.join("\n")}`;
|
|
|
855
962
|
} else if (monthlyDays >= 28) {
|
|
856
963
|
points = getRandomInt(100, 200);
|
|
857
964
|
}
|
|
965
|
+
if (meowEffect) {
|
|
966
|
+
tickets *= 2;
|
|
967
|
+
points *= 2;
|
|
968
|
+
effectMessage = "\n🐾 喵喵财源生效,获得双倍奖励!";
|
|
969
|
+
}
|
|
858
970
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
859
971
|
handle,
|
|
860
972
|
lastSign: now,
|
|
@@ -866,7 +978,9 @@ ${itemDetails.join("\n")}`;
|
|
|
866
978
|
itemId: 1,
|
|
867
979
|
quantity: (backpack?.quantity || 0) + tickets
|
|
868
980
|
}]);
|
|
869
|
-
return `签到成功!本月累计签到${monthlyDays}
|
|
981
|
+
return `签到成功!本月累计签到${monthlyDays}天,获得:
|
|
982
|
+
💰 金币 ×${points}
|
|
983
|
+
🪙 咕咕币 ×${tickets}` + effectMessage;
|
|
870
984
|
} catch (error) {
|
|
871
985
|
console.error("签到命令时发生错误:", error);
|
|
872
986
|
return "服务器繁忙,请稍后尝试。";
|
|
@@ -2098,21 +2212,41 @@ ${validTypes.join("、")}`;
|
|
|
2098
2212
|
if (!profile) return "您暂未绑定句柄";
|
|
2099
2213
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2100
2214
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2101
|
-
if (!
|
|
2215
|
+
if (!weapon) return "如果您想购买武器,请输入“购买 武器名称”。";
|
|
2216
|
+
if (!weaponConfig[weapon]) return "无效的武器名称,请重新输入。";
|
|
2102
2217
|
const config2 = weaponConfig[weapon];
|
|
2103
2218
|
const existingWeapons = await ctx.database.get("ggcevo_equipment", {
|
|
2104
2219
|
handle,
|
|
2105
2220
|
weaponId: config2.id
|
|
2106
2221
|
});
|
|
2107
2222
|
if (existingWeapons.length > 0) {
|
|
2108
|
-
return `你已经拥有${weapon}
|
|
2223
|
+
return `你已经拥有${weapon},无法重复购买。`;
|
|
2224
|
+
}
|
|
2225
|
+
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
2226
|
+
handle,
|
|
2227
|
+
wishname: "蚱蜢优购",
|
|
2228
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
2229
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
2230
|
+
isused: false
|
|
2231
|
+
}).then((records) => records[0]);
|
|
2232
|
+
let actualPrice = config2.price;
|
|
2233
|
+
let discountMessage = "";
|
|
2234
|
+
if (activeWish) {
|
|
2235
|
+
actualPrice = Math.floor(config2.price * 0.8);
|
|
2236
|
+
discountMessage = ` (祈愿优惠价,原价${config2.price})`;
|
|
2237
|
+
}
|
|
2238
|
+
if ((signInfo?.totalRewards || 0) < actualPrice) {
|
|
2239
|
+
return `金币不足,需要${actualPrice}枚金币${discountMessage}。`;
|
|
2109
2240
|
}
|
|
2110
|
-
if ((signInfo?.totalRewards || 0) < config2.price)
|
|
2111
|
-
return `金币不足,需要${config2.price}金币`;
|
|
2112
2241
|
await ctx.database.withTransaction(async () => {
|
|
2113
2242
|
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
2114
|
-
totalRewards: signInfo.totalRewards -
|
|
2243
|
+
totalRewards: signInfo.totalRewards - actualPrice
|
|
2115
2244
|
});
|
|
2245
|
+
if (activeWish) {
|
|
2246
|
+
await ctx.database.set("ggcevo_Wish_Record", { id: activeWish.id }, {
|
|
2247
|
+
isused: true
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2116
2250
|
await ctx.database.upsert("ggcevo_equipment", [{
|
|
2117
2251
|
handle,
|
|
2118
2252
|
weaponId: config2.id,
|
|
@@ -2121,7 +2255,12 @@ ${validTypes.join("、")}`;
|
|
|
2121
2255
|
equipped: false
|
|
2122
2256
|
}], ["handle", "weaponId"]);
|
|
2123
2257
|
});
|
|
2124
|
-
|
|
2258
|
+
let message = `成功购买 ${weapon}!花费 ${actualPrice}枚金币${discountMessage}。`;
|
|
2259
|
+
if (activeWish) {
|
|
2260
|
+
message += `
|
|
2261
|
+
🦗 蚱蜢优购祈愿已使用,下次购买将恢复原价。`;
|
|
2262
|
+
}
|
|
2263
|
+
return message + "\n输入“武器列表”查看你的武器库。";
|
|
2125
2264
|
});
|
|
2126
2265
|
ctx.command("ggcevo/武器列表").action(async ({ session }) => {
|
|
2127
2266
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
@@ -2186,7 +2325,7 @@ ${validTypes.join("、")}`;
|
|
|
2186
2325
|
});
|
|
2187
2326
|
ctx.command("ggcevo/升级 <weapon>", "升级武器伤害").alias("升级武器").action(async ({ session }, weapon) => {
|
|
2188
2327
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2189
|
-
if (!profile) return "
|
|
2328
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
2190
2329
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2191
2330
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2192
2331
|
const [equipment] = await ctx.database.get("ggcevo_equipment", {
|
|
@@ -2194,34 +2333,60 @@ ${validTypes.join("、")}`;
|
|
|
2194
2333
|
weaponId: weaponConfig[weapon]?.id
|
|
2195
2334
|
});
|
|
2196
2335
|
if (!weapon) return "您没有输入需要升级的武器名称。";
|
|
2197
|
-
if (!equipment) return "
|
|
2198
|
-
if (equipment.level >= 6) return "
|
|
2199
|
-
const
|
|
2200
|
-
if ((signInfo?.totalRewards || 0) < upgradeCost)
|
|
2201
|
-
return `需要${upgradeCost}金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
2202
|
-
await ctx.database.set("ggcevo_equipment", {
|
|
2336
|
+
if (!equipment) return "尚未获得该武器。";
|
|
2337
|
+
if (equipment.level >= 6) return "该武器已达最大升级等级。";
|
|
2338
|
+
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
2203
2339
|
handle,
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
});
|
|
2209
|
-
|
|
2210
|
-
|
|
2340
|
+
wishname: "灵狐升运",
|
|
2341
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
2342
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
2343
|
+
isused: false
|
|
2344
|
+
}).then((records) => records[0]);
|
|
2345
|
+
let baseCost = [1050, 1450, 1850, 2250, 2650, 3050][equipment.level];
|
|
2346
|
+
let actualCost = baseCost;
|
|
2347
|
+
let discountMessage = "";
|
|
2348
|
+
if (activeWish) {
|
|
2349
|
+
actualCost = Math.floor(baseCost * 0.8);
|
|
2350
|
+
discountMessage = ` (祈愿优惠价,原价${baseCost})`;
|
|
2351
|
+
}
|
|
2352
|
+
if ((signInfo?.totalRewards || 0) < actualCost)
|
|
2353
|
+
return `需要${actualCost}枚金币${discountMessage},当前持有:${signInfo?.totalRewards || 0}。`;
|
|
2354
|
+
await ctx.database.withTransaction(async () => {
|
|
2355
|
+
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
2356
|
+
totalRewards: signInfo.totalRewards - actualCost
|
|
2357
|
+
});
|
|
2358
|
+
await ctx.database.set("ggcevo_equipment", {
|
|
2359
|
+
handle,
|
|
2360
|
+
weaponId: weaponConfig[weapon].id
|
|
2361
|
+
}, {
|
|
2362
|
+
level: equipment.level + 1,
|
|
2363
|
+
modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
|
|
2364
|
+
});
|
|
2365
|
+
if (activeWish) {
|
|
2366
|
+
await ctx.database.set("ggcevo_Wish_Record", { id: activeWish.id }, {
|
|
2367
|
+
isused: true
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2211
2370
|
});
|
|
2212
|
-
const baseDamage = weaponConfig[weapon].damage * (1 + 0.1 * (equipment.level + 1));
|
|
2213
2371
|
const newLevel = equipment.level + 1;
|
|
2372
|
+
const baseDamage = weaponConfig[weapon].damage * (1 + 0.1 * newLevel);
|
|
2214
2373
|
const slots = Math.floor(newLevel / 3) + 1;
|
|
2215
|
-
|
|
2374
|
+
let message = `${weapon} 升级成功!花费${actualCost}枚金币${discountMessage}。`;
|
|
2375
|
+
if (activeWish) {
|
|
2376
|
+
message += `
|
|
2377
|
+
🦊 灵狐升运祈愿已生效,下次升级将恢复原价。`;
|
|
2378
|
+
}
|
|
2379
|
+
return `${message}
|
|
2380
|
+
当前等级:${newLevel},伤害:${baseDamage},可用改装槽:${slots}个。`;
|
|
2216
2381
|
});
|
|
2217
|
-
ctx.command("ggcevo/改装 <weapon> [mod]", "
|
|
2382
|
+
ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").alias("改装武器").action(async ({ session }, weapon, mod) => {
|
|
2218
2383
|
const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
|
|
2219
2384
|
const generateModList = /* @__PURE__ */ __name(() => {
|
|
2220
2385
|
if (!isValidWeapon) {
|
|
2221
2386
|
return Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(formatModEntry).join("\n\n");
|
|
2222
2387
|
}
|
|
2223
2388
|
const exclusiveMods = Object.entries(modConfig).filter(([_, m]) => m.isExclusive && m.exclusiveTo === weapon).map(formatModEntry);
|
|
2224
|
-
return exclusiveMods.length ? exclusiveMods.join("\n\n") : "
|
|
2389
|
+
return exclusiveMods.length ? exclusiveMods.join("\n\n") : "该武器暂无专属模块";
|
|
2225
2390
|
}, "generateModList");
|
|
2226
2391
|
const formatModEntry = /* @__PURE__ */ __name(([name2, config2]) => [
|
|
2227
2392
|
`【${name2}】${config2.isExclusive ? ` (专属:${config2.exclusiveTo})` : ""}`,
|
|
@@ -2231,8 +2396,8 @@ ${validTypes.join("、")}`;
|
|
|
2231
2396
|
].filter(Boolean).join("\n"), "formatModEntry");
|
|
2232
2397
|
if (!mod || !modConfig[mod]) {
|
|
2233
2398
|
return [
|
|
2234
|
-
isValidWeapon ? `🛠️ ${weapon}
|
|
2235
|
-
isValidWeapon ? `使用「改装 ${weapon}
|
|
2399
|
+
isValidWeapon ? `🛠️ ${weapon} 专属模块 🛠️` : "🛠️ 通用武器模块 🛠️",
|
|
2400
|
+
isValidWeapon ? `使用「改装 ${weapon} 模块」安装专属模块` : weapon ? "※ 无效武器名称,请使用「改装 武器名称 模块」安装通用模块" : "※ 输入「改装 武器名称」查询专属模块\n※ 安装模块:「改装 武器名称 模块」",
|
|
2236
2401
|
"====================",
|
|
2237
2402
|
generateModList()
|
|
2238
2403
|
].join("\n\n");
|
|
@@ -2249,17 +2414,17 @@ ${validTypes.join("、")}`;
|
|
|
2249
2414
|
const modInfo = modConfig[mod];
|
|
2250
2415
|
if (modInfo.isExclusive) {
|
|
2251
2416
|
if (modInfo.exclusiveTo !== weapon) {
|
|
2252
|
-
return `❌ 该模块只能安装在${modInfo.exclusiveTo}
|
|
2417
|
+
return `❌ 该模块只能安装在${modInfo.exclusiveTo}上。`;
|
|
2253
2418
|
}
|
|
2254
2419
|
const hasExclusive = equipment.installedMods.some((m) => modConfig[m]?.isExclusive);
|
|
2255
|
-
if (hasExclusive) return "❌
|
|
2420
|
+
if (hasExclusive) return "❌ 每个武器只能安装一个专属模块。";
|
|
2256
2421
|
}
|
|
2257
2422
|
if (equipment.installedMods.length >= equipment.modificationSlots)
|
|
2258
|
-
return "
|
|
2423
|
+
return "改装槽已满,升级武器等级至3/6级的时候会额外获得一个改装槽。";
|
|
2259
2424
|
if (equipment.installedMods.includes(mod))
|
|
2260
|
-
return "
|
|
2425
|
+
return "已安装相同模块。";
|
|
2261
2426
|
if ((signInfo?.totalRewards || 0) < modInfo.cost)
|
|
2262
|
-
return `需要${modInfo.cost}
|
|
2427
|
+
return `需要${modInfo.cost}枚金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
2263
2428
|
await ctx.database.set("ggcevo_equipment", {
|
|
2264
2429
|
handle,
|
|
2265
2430
|
weaponId: weaponConfig[weapon].id
|
|
@@ -2273,7 +2438,7 @@ ${validTypes.join("、")}`;
|
|
|
2273
2438
|
const config2 = modConfig[m];
|
|
2274
2439
|
return [
|
|
2275
2440
|
`【${m}】`,
|
|
2276
|
-
`安装费用:${config2.cost}
|
|
2441
|
+
`安装费用:${config2.cost}枚金币`,
|
|
2277
2442
|
`效果:${config2.effect}`
|
|
2278
2443
|
].join("\n");
|
|
2279
2444
|
}).join("\n\n");
|
|
@@ -2329,7 +2494,7 @@ ${validTypes.join("、")}`;
|
|
|
2329
2494
|
if (!bossGroup) return "无法获取BOSS组信息,请联系管理员。";
|
|
2330
2495
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
2331
2496
|
const [weaponName, weaponData] = weaponConfigEntry;
|
|
2332
|
-
const { damage: baseDamage, hasCrit } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
2497
|
+
const { damage: baseDamage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
2333
2498
|
const actualDamage = Math.min(baseDamage, targetBoss.HP);
|
|
2334
2499
|
const updatedHP = targetBoss.HP - actualDamage;
|
|
2335
2500
|
const isDefeated = updatedHP <= 0;
|
|
@@ -2377,7 +2542,7 @@ ${validTypes.join("、")}`;
|
|
|
2377
2542
|
{ respawnTime }
|
|
2378
2543
|
);
|
|
2379
2544
|
const damageRecords = await ctx.database.select("ggcevo_boss_damage").where({ bossGroupId: targetBoss.groupId }).orderBy("totalDamage", "desc").execute();
|
|
2380
|
-
|
|
2545
|
+
let rewardMessages = [];
|
|
2381
2546
|
const updatePromises = [];
|
|
2382
2547
|
const rewardMap = /* @__PURE__ */ new Map();
|
|
2383
2548
|
if (damageRecords.length > 0) {
|
|
@@ -2424,6 +2589,52 @@ ${validTypes.join("、")}`;
|
|
|
2424
2589
|
});
|
|
2425
2590
|
rewardMessages.push(`其他参与者各获得: 5 咕咕币 + 200 金币`);
|
|
2426
2591
|
}
|
|
2592
|
+
const doubleRewardPlayers = /* @__PURE__ */ new Map();
|
|
2593
|
+
for (const record of damageRecords) {
|
|
2594
|
+
const [elfEffect] = await ctx.database.get("ggcevo_Wish_Record", {
|
|
2595
|
+
handle: record.handle,
|
|
2596
|
+
wishname: "精灵双倍",
|
|
2597
|
+
isused: false,
|
|
2598
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
2599
|
+
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
2600
|
+
});
|
|
2601
|
+
if (elfEffect) {
|
|
2602
|
+
doubleRewardPlayers.set(record.handle, {
|
|
2603
|
+
effect: elfEffect,
|
|
2604
|
+
originalReward: {
|
|
2605
|
+
guguCoins: rewardMap.get(record.handle)?.guguCoins || 0,
|
|
2606
|
+
gold: rewardMap.get(record.handle)?.gold || 0
|
|
2607
|
+
}
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
if (doubleRewardPlayers.size > 0) {
|
|
2612
|
+
await ctx.database.withTransaction(async () => {
|
|
2613
|
+
for (const [handle2, data] of doubleRewardPlayers) {
|
|
2614
|
+
const reward = rewardMap.get(handle2);
|
|
2615
|
+
reward.guguCoins = data.originalReward.guguCoins * 2;
|
|
2616
|
+
reward.gold = data.originalReward.gold * 2;
|
|
2617
|
+
await ctx.database.set(
|
|
2618
|
+
"ggcevo_Wish_Record",
|
|
2619
|
+
{ id: data.effect.id },
|
|
2620
|
+
{ isused: true }
|
|
2621
|
+
);
|
|
2622
|
+
}
|
|
2623
|
+
});
|
|
2624
|
+
rewardMessages = rewardMessages.map((msg) => {
|
|
2625
|
+
const match = msg.match(/(\d+\.) (.+?) 获得奖励/);
|
|
2626
|
+
if (match) {
|
|
2627
|
+
const playerName = match[2];
|
|
2628
|
+
const targetHandle = [...rewardMap.keys()].find(
|
|
2629
|
+
(key) => rewardMap.get(key).playerName === playerName
|
|
2630
|
+
);
|
|
2631
|
+
if (targetHandle && doubleRewardPlayers.has(targetHandle)) {
|
|
2632
|
+
return `${match[1]} ${playerName} 🧚 获得奖励: ${rewardMap.get(targetHandle).guguCoins} 咕咕币 + ${rewardMap.get(targetHandle).gold} 金币 (双倍生效)`;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
return msg;
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2427
2638
|
for (const [handle2, reward] of rewardMap) {
|
|
2428
2639
|
const signPromise = (async () => {
|
|
2429
2640
|
const [existingSign2] = await ctx.database.get("ggcevo_sign", { handle: handle2 });
|
|
@@ -2509,6 +2720,10 @@ ${validTypes.join("、")}`;
|
|
|
2509
2720
|
}
|
|
2510
2721
|
const resultMessage = [
|
|
2511
2722
|
`🔥 ${session.username} 使用武器 ${weaponName} 对 ${targetBoss.name} 发起攻击!`,
|
|
2723
|
+
...effectMessage.length > 0 ? [
|
|
2724
|
+
// 新增效果反馈
|
|
2725
|
+
`💫 祈愿效果:${effectMessage.join(" | ")}`
|
|
2726
|
+
] : [],
|
|
2512
2727
|
`造成伤害:${actualDamage}${hasCrit ? "(✨ 暴击!)" : ""}`,
|
|
2513
2728
|
`获得金币:${actualDamage}`,
|
|
2514
2729
|
`目标剩余HP:${isDefeated ? 0 : updatedHP}/${targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions[0].maxHP}`,
|
|
@@ -2613,6 +2828,81 @@ ${validTypes.join("、")}`;
|
|
|
2613
2828
|
}
|
|
2614
2829
|
return result.join("\n");
|
|
2615
2830
|
});
|
|
2831
|
+
ctx.command("ggcevo/祈愿").action(async (argv) => {
|
|
2832
|
+
const session = argv.session;
|
|
2833
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2834
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
2835
|
+
const { regionId, realmId, profileId } = profile;
|
|
2836
|
+
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2837
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2838
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
2839
|
+
const [sign] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2840
|
+
if (!sign || sign.totalRewards < 50) return "需要50金币进行祈愿,当前金币不足。";
|
|
2841
|
+
const now = /* @__PURE__ */ new Date();
|
|
2842
|
+
const [latestWish] = await ctx.database.get("ggcevo_Wish_Record", { handle }, {
|
|
2843
|
+
sort: { endTime: "desc" },
|
|
2844
|
+
limit: 1
|
|
2845
|
+
});
|
|
2846
|
+
if (latestWish?.endTime > now) {
|
|
2847
|
+
const allEffects = [...wishConfig.common, ...wishConfig.rare];
|
|
2848
|
+
const currentEffect = allEffects.find((e) => e.name === latestWish.wishname) ?? {
|
|
2849
|
+
name: "未知效果",
|
|
2850
|
+
effect: "效果信息暂不可用"
|
|
2851
|
+
};
|
|
2852
|
+
const endTime2 = latestWish.endTime.toLocaleString("zh-CN", {
|
|
2853
|
+
timeZone: "Asia/Shanghai",
|
|
2854
|
+
hour12: false,
|
|
2855
|
+
year: "numeric",
|
|
2856
|
+
month: "2-digit",
|
|
2857
|
+
day: "2-digit",
|
|
2858
|
+
hour: "2-digit",
|
|
2859
|
+
minute: "2-digit"
|
|
2860
|
+
});
|
|
2861
|
+
return `当前祈愿效果:【${currentEffect.name}】${currentEffect.effect}
|
|
2862
|
+
🕒 祈愿冷却中,下次可祈愿时间:${endTime2}`;
|
|
2863
|
+
}
|
|
2864
|
+
let newGold = sign.totalRewards - 50;
|
|
2865
|
+
const isRare = Math.random() < 0.05;
|
|
2866
|
+
const pool = isRare ? wishConfig.rare : wishConfig.common;
|
|
2867
|
+
const effect = pool[Math.floor(Math.random() * pool.length)];
|
|
2868
|
+
switch (effect.name) {
|
|
2869
|
+
case "金柚赐福":
|
|
2870
|
+
newGold += 250;
|
|
2871
|
+
break;
|
|
2872
|
+
case "酥手空空":
|
|
2873
|
+
newGold = Math.max(0, newGold - 50);
|
|
2874
|
+
break;
|
|
2875
|
+
case "夜市赠礼":
|
|
2876
|
+
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
2877
|
+
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2878
|
+
handle,
|
|
2879
|
+
itemId: 1,
|
|
2880
|
+
quantity: (backpack?.quantity || 0) + 5
|
|
2881
|
+
}]);
|
|
2882
|
+
break;
|
|
2883
|
+
}
|
|
2884
|
+
await ctx.database.set("ggcevo_sign", { handle }, { totalRewards: newGold });
|
|
2885
|
+
const startTime = /* @__PURE__ */ new Date();
|
|
2886
|
+
const endTime = new Date(startTime.getTime() + 7 * 24 * 60 * 60 * 1e3);
|
|
2887
|
+
await ctx.database.create("ggcevo_Wish_Record", {
|
|
2888
|
+
handle,
|
|
2889
|
+
wishname: effect.name,
|
|
2890
|
+
startTime,
|
|
2891
|
+
endTime,
|
|
2892
|
+
isused: false
|
|
2893
|
+
});
|
|
2894
|
+
const formattedEndTime = endTime.toLocaleString("zh-CN", {
|
|
2895
|
+
timeZone: "Asia/Shanghai",
|
|
2896
|
+
hour12: false,
|
|
2897
|
+
year: "numeric",
|
|
2898
|
+
month: "2-digit",
|
|
2899
|
+
day: "2-digit",
|
|
2900
|
+
hour: "2-digit",
|
|
2901
|
+
minute: "2-digit"
|
|
2902
|
+
});
|
|
2903
|
+
return `✨ 祈愿成功!获得【${effect.name}】效果:${effect.effect}
|
|
2904
|
+
⏳ 效果持续至 ${formattedEndTime}`;
|
|
2905
|
+
});
|
|
2616
2906
|
}
|
|
2617
2907
|
__name(apply, "apply");
|
|
2618
2908
|
function simpleDraw() {
|
|
@@ -2681,6 +2971,12 @@ function formatDate(d) {
|
|
|
2681
2971
|
});
|
|
2682
2972
|
}
|
|
2683
2973
|
__name(formatDate, "formatDate");
|
|
2974
|
+
function createHpBar(current, max) {
|
|
2975
|
+
const ratio = current / max;
|
|
2976
|
+
const filled = Math.floor(ratio * 20);
|
|
2977
|
+
return "▰".repeat(filled) + "▱".repeat(20 - filled);
|
|
2978
|
+
}
|
|
2979
|
+
__name(createHpBar, "createHpBar");
|
|
2684
2980
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2685
2981
|
0 && (module.exports = {
|
|
2686
2982
|
Config,
|