koishi-plugin-ggcevo-game 1.3.23 → 1.3.25
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 +0 -6
- package/lib/index.js +567 -484
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -41,8 +41,8 @@ var Config = import_koishi.Schema.intersect([
|
|
|
41
41
|
}).description("赛季配置"),
|
|
42
42
|
// 核心功能开关组
|
|
43
43
|
import_koishi.Schema.object({
|
|
44
|
-
signrequire: import_koishi.Schema.boolean().description("游戏对局签到要求").default(
|
|
45
|
-
autorank: import_koishi.Schema.boolean().description("自动同步天梯数据").default(
|
|
44
|
+
signrequire: import_koishi.Schema.boolean().description("游戏对局签到要求").default(false),
|
|
45
|
+
autorank: import_koishi.Schema.boolean().description("自动同步天梯数据").default(false)
|
|
46
46
|
}).description("功能开关"),
|
|
47
47
|
// 对战系统配置组
|
|
48
48
|
import_koishi.Schema.object({
|
|
@@ -184,13 +184,6 @@ function apply(ctx, config) {
|
|
|
184
184
|
}, {
|
|
185
185
|
primary: "handle"
|
|
186
186
|
});
|
|
187
|
-
ctx.model.extend("ggcevo_achievements", {
|
|
188
|
-
handle: "string",
|
|
189
|
-
achievementname: "string",
|
|
190
|
-
gaintime: "timestamp"
|
|
191
|
-
}, {
|
|
192
|
-
primary: ["handle", "achievementname"]
|
|
193
|
-
});
|
|
194
187
|
ctx.model.extend("ggcevo_pk", {
|
|
195
188
|
handle: "string",
|
|
196
189
|
name: "string",
|
|
@@ -298,8 +291,9 @@ function apply(ctx, config) {
|
|
|
298
291
|
type: "实弹武器",
|
|
299
292
|
damage: 10,
|
|
300
293
|
description: "标准配置武器,中距离作战利器",
|
|
294
|
+
specialeffect: "",
|
|
301
295
|
price: 100,
|
|
302
|
-
redCrystalCost:
|
|
296
|
+
redCrystalCost: 5,
|
|
303
297
|
isantiair: true,
|
|
304
298
|
tagEffects: {
|
|
305
299
|
"轻甲": 1.5
|
|
@@ -311,6 +305,7 @@ function apply(ctx, config) {
|
|
|
311
305
|
type: "能量武器",
|
|
312
306
|
damage: 23,
|
|
313
307
|
description: "先进激光武器,远距离精准打击",
|
|
308
|
+
specialeffect: "",
|
|
314
309
|
price: 300,
|
|
315
310
|
redCrystalCost: 5,
|
|
316
311
|
isantiair: true,
|
|
@@ -325,6 +320,7 @@ function apply(ctx, config) {
|
|
|
325
320
|
type: "热能武器",
|
|
326
321
|
damage: 20,
|
|
327
322
|
description: "基于热能的强大武器,烧烬一切",
|
|
323
|
+
specialeffect: "",
|
|
328
324
|
price: 450,
|
|
329
325
|
redCrystalCost: 5,
|
|
330
326
|
isantiair: false,
|
|
@@ -339,8 +335,9 @@ function apply(ctx, config) {
|
|
|
339
335
|
type: "能量武器",
|
|
340
336
|
damage: 28,
|
|
341
337
|
description: "由激光步枪改良而来,高效的对重甲武器",
|
|
338
|
+
specialeffect: "",
|
|
342
339
|
price: 850,
|
|
343
|
-
redCrystalCost:
|
|
340
|
+
redCrystalCost: 10,
|
|
344
341
|
isantiair: true,
|
|
345
342
|
tagEffects: {
|
|
346
343
|
"重甲": 2,
|
|
@@ -353,8 +350,9 @@ function apply(ctx, config) {
|
|
|
353
350
|
type: "实弹武器",
|
|
354
351
|
damage: 12,
|
|
355
352
|
description: "一种改造后的采矿切割机,有效对抗重甲目标",
|
|
353
|
+
specialeffect: "",
|
|
356
354
|
price: 150,
|
|
357
|
-
redCrystalCost:
|
|
355
|
+
redCrystalCost: 5,
|
|
358
356
|
isantiair: true,
|
|
359
357
|
tagEffects: {
|
|
360
358
|
"重甲": 1.5,
|
|
@@ -367,6 +365,7 @@ function apply(ctx, config) {
|
|
|
367
365
|
type: "实弹武器",
|
|
368
366
|
damage: 28,
|
|
369
367
|
description: "近距离攻击武器,专为遭遇战设计使用",
|
|
368
|
+
specialeffect: "",
|
|
370
369
|
price: 325,
|
|
371
370
|
redCrystalCost: 5,
|
|
372
371
|
isantiair: false,
|
|
@@ -380,6 +379,7 @@ function apply(ctx, config) {
|
|
|
380
379
|
type: "实弹武器",
|
|
381
380
|
damage: 50,
|
|
382
381
|
description: "用于隐秘射击的最佳武器,但是无法穿透护甲",
|
|
382
|
+
specialeffect: "",
|
|
383
383
|
price: 550,
|
|
384
384
|
redCrystalCost: 10,
|
|
385
385
|
isantiair: true,
|
|
@@ -393,6 +393,7 @@ function apply(ctx, config) {
|
|
|
393
393
|
type: "热能武器",
|
|
394
394
|
damage: 25,
|
|
395
395
|
description: "喷射稳定的液氮恒流,对长时间接触者造成致命的损伤",
|
|
396
|
+
specialeffect: "",
|
|
396
397
|
price: 775,
|
|
397
398
|
redCrystalCost: 10,
|
|
398
399
|
isantiair: false,
|
|
@@ -406,6 +407,7 @@ function apply(ctx, config) {
|
|
|
406
407
|
type: "能量武器",
|
|
407
408
|
damage: 25,
|
|
408
409
|
description: "一种经过改造的电动工具,可对近距离的目标放出高压电",
|
|
410
|
+
specialeffect: "",
|
|
409
411
|
price: 750,
|
|
410
412
|
redCrystalCost: 10,
|
|
411
413
|
isantiair: true,
|
|
@@ -418,13 +420,27 @@ function apply(ctx, config) {
|
|
|
418
420
|
id: 10,
|
|
419
421
|
type: "热能武器",
|
|
420
422
|
damage: 24,
|
|
421
|
-
description: "
|
|
423
|
+
description: "一种高度危险性的武器,设计用辐射照射并伤害敌人",
|
|
424
|
+
specialeffect: "攻击使生物目标(无机械标签)叠加“辐射”层数,每层使其受到的伤害+1%",
|
|
422
425
|
price: 825,
|
|
423
|
-
redCrystalCost:
|
|
426
|
+
redCrystalCost: 10,
|
|
424
427
|
isantiair: true,
|
|
425
428
|
tagEffects: {
|
|
426
429
|
"生物": 1.2
|
|
427
430
|
}
|
|
431
|
+
},
|
|
432
|
+
"中子步枪": {
|
|
433
|
+
id: 11,
|
|
434
|
+
type: "能量武器",
|
|
435
|
+
damage: 30,
|
|
436
|
+
description: "激光步枪的变种,采用折射技术升级",
|
|
437
|
+
specialeffect: "",
|
|
438
|
+
price: 1450,
|
|
439
|
+
redCrystalCost: 15,
|
|
440
|
+
isantiair: true,
|
|
441
|
+
tagEffects: {
|
|
442
|
+
"灵能": 1.5
|
|
443
|
+
}
|
|
428
444
|
}
|
|
429
445
|
};
|
|
430
446
|
const SyndicatedItems = {
|
|
@@ -483,9 +499,15 @@ function apply(ctx, config) {
|
|
|
483
499
|
},
|
|
484
500
|
"助燃核心": {
|
|
485
501
|
cost: 2550,
|
|
486
|
-
effect: "对惧热目标改为造成
|
|
502
|
+
effect: "对惧热目标改为造成300%伤害; 对生物目标改为造成200%伤害",
|
|
487
503
|
exclusiveTo: "焚烧枪",
|
|
488
504
|
isExclusive: true
|
|
505
|
+
},
|
|
506
|
+
"光束曲射晶片": {
|
|
507
|
+
cost: 2250,
|
|
508
|
+
effect: "攻击目标后,若有其他的存活异形,则对其造成50%的武器基础伤害",
|
|
509
|
+
exclusiveTo: "碎骨步枪",
|
|
510
|
+
isExclusive: true
|
|
489
511
|
}
|
|
490
512
|
};
|
|
491
513
|
const wishConfig = {
|
|
@@ -520,11 +542,11 @@ function apply(ctx, config) {
|
|
|
520
542
|
},
|
|
521
543
|
{
|
|
522
544
|
name: "精灵双倍",
|
|
523
|
-
effect: "
|
|
545
|
+
effect: "下一次击败首领时可获得双倍的金币和咕咕币奖励"
|
|
524
546
|
},
|
|
525
547
|
{
|
|
526
548
|
name: "喵喵财源",
|
|
527
|
-
effect: "
|
|
549
|
+
effect: "签到获得双倍的金币和咕咕币"
|
|
528
550
|
},
|
|
529
551
|
{
|
|
530
552
|
name: "暴击韵律",
|
|
@@ -1036,7 +1058,11 @@ function apply(ctx, config) {
|
|
|
1036
1058
|
totalAdditive += wishAdditive.value;
|
|
1037
1059
|
if (wishAdditive.message) effectMessage.push(wishAdditive.message);
|
|
1038
1060
|
const [rankRecord] = await ctx2.database.get("ggcevo_rank", { handle, rankseason: config.rankseason });
|
|
1039
|
-
|
|
1061
|
+
const rankAddResult = calculateRankAdditive(rankRecord);
|
|
1062
|
+
totalAdditive += rankAddResult.value;
|
|
1063
|
+
if (rankAddResult.message) {
|
|
1064
|
+
effectMessage.push(rankAddResult.message);
|
|
1065
|
+
}
|
|
1040
1066
|
let finalDamage = baseDamage * (1 + totalAdditive);
|
|
1041
1067
|
const minDamage = baseDamage * 0.01;
|
|
1042
1068
|
if (finalDamage < minDamage) {
|
|
@@ -1063,7 +1089,8 @@ function apply(ctx, config) {
|
|
|
1063
1089
|
async function calculateTagMultiplier(weaponData, tags, equippedWeapon) {
|
|
1064
1090
|
const MOD_EFFECTS = [
|
|
1065
1091
|
{ mod: "裂甲核心", tag: "重甲", value: 1.2 },
|
|
1066
|
-
{ mod: "助燃核心", tag: "惧热", value:
|
|
1092
|
+
{ mod: "助燃核心", tag: "惧热", value: 3 },
|
|
1093
|
+
{ mod: "助燃核心", tag: "生物", value: 2 }
|
|
1067
1094
|
];
|
|
1068
1095
|
let totalAdditive = 0;
|
|
1069
1096
|
for (const tag of tags) {
|
|
@@ -1184,8 +1211,16 @@ function apply(ctx, config) {
|
|
|
1184
1211
|
}
|
|
1185
1212
|
__name(calculateWishAdditive, "calculateWishAdditive");
|
|
1186
1213
|
function calculateRankAdditive(rankRecord) {
|
|
1187
|
-
if (!rankRecord || rankRecord.rank <= 0) return 0;
|
|
1188
|
-
|
|
1214
|
+
if (!rankRecord || rankRecord.rank <= 0) return { value: 0, message: "" };
|
|
1215
|
+
const value = Math.floor(rankRecord.rank / 400) * 0.01;
|
|
1216
|
+
if (value > 0) {
|
|
1217
|
+
const percentage = Math.round(value * 100);
|
|
1218
|
+
return {
|
|
1219
|
+
value,
|
|
1220
|
+
message: `🏆 排名加成:攻击伤害+${percentage}%`
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
return { value: 0, message: "" };
|
|
1189
1224
|
}
|
|
1190
1225
|
__name(calculateRankAdditive, "calculateRankAdditive");
|
|
1191
1226
|
const initDefaultItems = {
|
|
@@ -1619,7 +1654,7 @@ function apply(ctx, config) {
|
|
|
1619
1654
|
}, "handleStructuralArmor"),
|
|
1620
1655
|
// 吸血效果处理(返回综合系数)
|
|
1621
1656
|
handleBloodEffects: /* @__PURE__ */ __name(function(targetBoss, currentHP, maxHP) {
|
|
1622
|
-
if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("
|
|
1657
|
+
if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("吐血")) return null;
|
|
1623
1658
|
const bloodStacks = targetBoss.Skillcountpoints || 0;
|
|
1624
1659
|
let damageMultiplier = 0;
|
|
1625
1660
|
const messages = [];
|
|
@@ -1641,7 +1676,7 @@ function apply(ctx, config) {
|
|
|
1641
1676
|
return { damageMultiplier, messages };
|
|
1642
1677
|
}, "handleBloodEffects"),
|
|
1643
1678
|
handleBloodCount: /* @__PURE__ */ __name(async function(ctx2, targetBoss, currentHP, maxHP) {
|
|
1644
|
-
if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食")
|
|
1679
|
+
if (!targetBoss.skills.includes("吸血唾液") || !targetBoss.skills.includes("进食")) {
|
|
1645
1680
|
return null;
|
|
1646
1681
|
}
|
|
1647
1682
|
let messages = [];
|
|
@@ -1678,12 +1713,15 @@ function apply(ctx, config) {
|
|
|
1678
1713
|
const messages = [];
|
|
1679
1714
|
const hasRadiation = targetBoss.skills.includes("辐射");
|
|
1680
1715
|
const currentLayers = targetBoss.Vulnerability || 0;
|
|
1681
|
-
const
|
|
1716
|
+
const skillUpdates = [];
|
|
1682
1717
|
const newLayers = hasRadiation ? Math.min(currentLayers + 1, 100) : 1;
|
|
1683
1718
|
let layerMsg;
|
|
1684
|
-
0;
|
|
1685
1719
|
if (!hasRadiation) {
|
|
1686
1720
|
layerMsg = `☢️ ${targetBoss.name} 获得【辐射】效果`;
|
|
1721
|
+
skillUpdates.push({
|
|
1722
|
+
name: targetBoss.name,
|
|
1723
|
+
add: ["辐射"]
|
|
1724
|
+
});
|
|
1687
1725
|
} else if (newLayers === currentLayers) {
|
|
1688
1726
|
layerMsg = `☢️ 辐射层数已达上限(100层)`;
|
|
1689
1727
|
} else {
|
|
@@ -1693,13 +1731,11 @@ function apply(ctx, config) {
|
|
|
1693
1731
|
"ggcevo_boss",
|
|
1694
1732
|
{ name: targetBoss.name },
|
|
1695
1733
|
{
|
|
1696
|
-
skills: Array.from(new Set(newSkills)),
|
|
1697
|
-
// 显式类型断言
|
|
1698
1734
|
Vulnerability: newLayers
|
|
1699
1735
|
}
|
|
1700
1736
|
);
|
|
1701
1737
|
messages.push(layerMsg);
|
|
1702
|
-
return { messages };
|
|
1738
|
+
return { messages, skillUpdates };
|
|
1703
1739
|
}, "handleGammaRadiation"),
|
|
1704
1740
|
// 伽马枪辐射计算(返回增伤系数)
|
|
1705
1741
|
calculateRadiationDamage: /* @__PURE__ */ __name((targetBoss) => {
|
|
@@ -1812,6 +1848,7 @@ function apply(ctx, config) {
|
|
|
1812
1848
|
const gammaRadResult = await this.handleGammaRadiation(ctx2, targetBoss, weaponName);
|
|
1813
1849
|
if (gammaRadResult) {
|
|
1814
1850
|
messages.push(...gammaRadResult.messages);
|
|
1851
|
+
skillUpdates.push(...gammaRadResult.skillUpdates);
|
|
1815
1852
|
}
|
|
1816
1853
|
return {
|
|
1817
1854
|
currentHP,
|
|
@@ -1820,40 +1857,71 @@ function apply(ctx, config) {
|
|
|
1820
1857
|
initialDamage: finalDamage
|
|
1821
1858
|
};
|
|
1822
1859
|
}, "handlePassives"),
|
|
1823
|
-
//
|
|
1860
|
+
// 应用技能更新到数据库(优化合并同名boss的更新)
|
|
1824
1861
|
applySkillUpdates: /* @__PURE__ */ __name(async (ctx2, skillUpdates) => {
|
|
1825
|
-
const
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1862
|
+
const mergedUpdates = skillUpdates.reduce((acc, update) => {
|
|
1863
|
+
const existing = acc.find((u) => u.name === update.name);
|
|
1864
|
+
if (existing) {
|
|
1865
|
+
if (update.remove) {
|
|
1866
|
+
existing.remove = [.../* @__PURE__ */ new Set([...existing.remove, ...update.remove])];
|
|
1867
|
+
}
|
|
1868
|
+
if (update.add) {
|
|
1869
|
+
existing.add = [.../* @__PURE__ */ new Set([...existing.add, ...update.add])];
|
|
1870
|
+
}
|
|
1871
|
+
} else {
|
|
1872
|
+
acc.push({
|
|
1873
|
+
name: update.name,
|
|
1874
|
+
remove: [...new Set(update.remove || [])],
|
|
1875
|
+
add: [...new Set(update.add || [])]
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
return acc;
|
|
1879
|
+
}, []);
|
|
1880
|
+
const updates = mergedUpdates.map(async (update) => {
|
|
1881
|
+
const [boss] = await ctx2.database.get("ggcevo_boss", { name: update.name });
|
|
1882
|
+
if (!boss) return;
|
|
1883
|
+
let newSkills = [...boss.skills];
|
|
1884
|
+
if (update.remove?.length) {
|
|
1885
|
+
newSkills = newSkills.filter((s) => !update.remove.includes(s));
|
|
1886
|
+
}
|
|
1887
|
+
if (update.add?.length) {
|
|
1888
|
+
newSkills = [...newSkills, ...update.add];
|
|
1889
|
+
newSkills = [...new Set(newSkills)];
|
|
1890
|
+
}
|
|
1832
1891
|
return ctx2.database.set(
|
|
1833
1892
|
"ggcevo_boss",
|
|
1834
1893
|
{ name: update.name },
|
|
1835
|
-
{ skills:
|
|
1836
|
-
// 去重
|
|
1894
|
+
{ skills: newSkills }
|
|
1837
1895
|
);
|
|
1838
1896
|
});
|
|
1839
1897
|
await Promise.all(updates);
|
|
1840
1898
|
}, "applySkillUpdates")
|
|
1841
1899
|
};
|
|
1842
|
-
async function handleBossDefeatRewards(ctx2, targetBoss
|
|
1900
|
+
async function handleBossDefeatRewards(ctx2, targetBoss) {
|
|
1843
1901
|
const damageRecords = await ctx2.database.select("ggcevo_boss_damage").where({
|
|
1844
1902
|
bossGroupId: targetBoss.groupId,
|
|
1845
1903
|
totalDamage: { $gt: 0 }
|
|
1846
1904
|
}).orderBy("totalDamage", "desc").execute();
|
|
1847
1905
|
const rewardMessages = [];
|
|
1848
1906
|
const rewardMap = /* @__PURE__ */ new Map();
|
|
1849
|
-
const updatePromises = [];
|
|
1850
1907
|
const handles = damageRecords.map((r) => r.handle);
|
|
1851
|
-
const pirateCleaners = await
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1908
|
+
const [pirateCleaners, doubleWishRecords] = await Promise.all([
|
|
1909
|
+
ctx2.database.get("ggcevo_careers", {
|
|
1910
|
+
handle: { $in: handles },
|
|
1911
|
+
group: "辛迪加海盗",
|
|
1912
|
+
career: "清洁工"
|
|
1913
|
+
}),
|
|
1914
|
+
// 获取双倍祈愿信息
|
|
1915
|
+
ctx2.database.get("ggcevo_Wish_Record", {
|
|
1916
|
+
handle: { $in: handles },
|
|
1917
|
+
wishname: "精灵双倍",
|
|
1918
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
1919
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
1920
|
+
isused: false
|
|
1921
|
+
})
|
|
1922
|
+
]);
|
|
1856
1923
|
const cleanerHandles = new Set(pirateCleaners.map((c) => c.handle));
|
|
1924
|
+
const doubleWishHandles = new Set(doubleWishRecords.map((r) => r.handle));
|
|
1857
1925
|
if (damageRecords.length > 0) {
|
|
1858
1926
|
const top20 = damageRecords.slice(0, 20);
|
|
1859
1927
|
top20.forEach((record, index) => {
|
|
@@ -1877,6 +1945,10 @@ function apply(ctx, config) {
|
|
|
1877
1945
|
gold = 1e3;
|
|
1878
1946
|
break;
|
|
1879
1947
|
}
|
|
1948
|
+
if (doubleWishHandles.has(record.handle)) {
|
|
1949
|
+
guguCoins *= 2;
|
|
1950
|
+
gold *= 2;
|
|
1951
|
+
}
|
|
1880
1952
|
let redCrystal = 0;
|
|
1881
1953
|
if (cleanerHandles.has(record.handle)) {
|
|
1882
1954
|
switch (true) {
|
|
@@ -1912,18 +1984,22 @@ function apply(ctx, config) {
|
|
|
1912
1984
|
const others = damageRecords.slice(20);
|
|
1913
1985
|
if (others.length > 0) {
|
|
1914
1986
|
others.forEach((record) => {
|
|
1987
|
+
let guguCoins = 3;
|
|
1988
|
+
let gold = 200;
|
|
1989
|
+
if (doubleWishHandles.has(record.handle)) {
|
|
1990
|
+
guguCoins *= 2;
|
|
1991
|
+
gold *= 2;
|
|
1992
|
+
}
|
|
1915
1993
|
const baseReward = {
|
|
1916
|
-
guguCoins
|
|
1917
|
-
gold
|
|
1994
|
+
guguCoins,
|
|
1995
|
+
gold,
|
|
1918
1996
|
redCrystal: cleanerHandles.has(record.handle) ? 3 : 0,
|
|
1919
1997
|
playerName: record.playerName
|
|
1920
1998
|
};
|
|
1921
1999
|
rewardMap.set(record.handle, baseReward);
|
|
1922
2000
|
});
|
|
1923
|
-
rewardMessages.push(`其他参与者各获得: 3 咕咕币 + 200 金币` + (cleanerHandles.size > 0 ? " (清洁工额外+3红晶)" : ""));
|
|
2001
|
+
rewardMessages.push(`其他参与者各获得: 3 咕咕币 + 200 金币` + (cleanerHandles.size > 0 ? " (清洁工额外+3红晶)" : "") + (doubleWishHandles.size > 0 ? " (精灵双倍祈愿玩家奖励翻倍)" : ""));
|
|
1924
2002
|
}
|
|
1925
|
-
const doubleRewardPlayers = await handleDoubleRewards(ctx2, damageRecords, rewardMap);
|
|
1926
|
-
await applyDoubleRewards(ctx2, doubleRewardPlayers, rewardMap, rewardMessages);
|
|
1927
2003
|
await ctx2.database.withTransaction(async () => {
|
|
1928
2004
|
for (const [handle, reward] of rewardMap) {
|
|
1929
2005
|
const [signData] = await ctx2.database.get("ggcevo_sign", { handle });
|
|
@@ -1953,58 +2029,6 @@ function apply(ctx, config) {
|
|
|
1953
2029
|
return { rewardMessages };
|
|
1954
2030
|
}
|
|
1955
2031
|
__name(handleBossDefeatRewards, "handleBossDefeatRewards");
|
|
1956
|
-
async function handleDoubleRewards(ctx2, damageRecords, rewardMap) {
|
|
1957
|
-
const doubleRewardPlayers = /* @__PURE__ */ new Map();
|
|
1958
|
-
for (const record of damageRecords) {
|
|
1959
|
-
const [elfEffect] = await ctx2.database.get("ggcevo_Wish_Record", {
|
|
1960
|
-
handle: record.handle,
|
|
1961
|
-
wishname: "精灵双倍",
|
|
1962
|
-
isused: false,
|
|
1963
|
-
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
1964
|
-
endTime: { $gte: /* @__PURE__ */ new Date() }
|
|
1965
|
-
});
|
|
1966
|
-
if (elfEffect) {
|
|
1967
|
-
doubleRewardPlayers.set(record.handle, {
|
|
1968
|
-
effect: elfEffect,
|
|
1969
|
-
originalReward: {
|
|
1970
|
-
guguCoins: rewardMap.get(record.handle)?.guguCoins || 0,
|
|
1971
|
-
gold: rewardMap.get(record.handle)?.gold || 0
|
|
1972
|
-
}
|
|
1973
|
-
});
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
return doubleRewardPlayers;
|
|
1977
|
-
}
|
|
1978
|
-
__name(handleDoubleRewards, "handleDoubleRewards");
|
|
1979
|
-
async function applyDoubleRewards(ctx2, doubleRewardPlayers, rewardMap, rewardMessages) {
|
|
1980
|
-
if (doubleRewardPlayers.size > 0) {
|
|
1981
|
-
await ctx2.database.withTransaction(async () => {
|
|
1982
|
-
for (const [handle, data] of doubleRewardPlayers) {
|
|
1983
|
-
const reward = rewardMap.get(handle);
|
|
1984
|
-
reward.guguCoins = data.originalReward.guguCoins * 2;
|
|
1985
|
-
reward.gold = data.originalReward.gold * 2;
|
|
1986
|
-
await ctx2.database.set(
|
|
1987
|
-
"ggcevo_Wish_Record",
|
|
1988
|
-
{ id: data.effect.id },
|
|
1989
|
-
{ isused: true }
|
|
1990
|
-
);
|
|
1991
|
-
}
|
|
1992
|
-
});
|
|
1993
|
-
rewardMessages.forEach((msg, index) => {
|
|
1994
|
-
const match = msg.match(/(\d+\.) (.+?) 获得奖励/);
|
|
1995
|
-
if (match) {
|
|
1996
|
-
const playerName = match[2];
|
|
1997
|
-
const targetHandle = [...rewardMap.keys()].find(
|
|
1998
|
-
(key) => rewardMap.get(key).playerName === playerName
|
|
1999
|
-
);
|
|
2000
|
-
if (targetHandle && doubleRewardPlayers.has(targetHandle)) {
|
|
2001
|
-
rewardMessages[index] = `${match[1]} ${playerName} 🧚 获得双倍奖励: ${rewardMap.get(targetHandle).guguCoins} 咕咕币 + ${rewardMap.get(targetHandle).gold} 金币(精灵双倍祈愿生效)`;
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
});
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
__name(applyDoubleRewards, "applyDoubleRewards");
|
|
2008
2032
|
async function checkTransferRequirements(ctx2, handle, profession) {
|
|
2009
2033
|
const [mainBoss] = await ctx2.database.get("ggcevo_boss", {
|
|
2010
2034
|
type: "主宰",
|
|
@@ -2131,18 +2155,18 @@ function apply(ctx, config) {
|
|
|
2131
2155
|
handle,
|
|
2132
2156
|
totalRewards: (signRecords[0]?.totalRewards || 0) + damageValue
|
|
2133
2157
|
}], ["handle"]);
|
|
2134
|
-
const damageRecords = await ctx.database.get("ggcevo_boss_damage", { handle });
|
|
2158
|
+
const [damageRecords] = await ctx.database.get("ggcevo_boss_damage", { handle });
|
|
2135
2159
|
await ctx.database.upsert("ggcevo_boss_damage", [{
|
|
2136
2160
|
handle,
|
|
2137
2161
|
playerName: session.username,
|
|
2138
|
-
totalDamage: (damageRecords
|
|
2139
|
-
attackCount: damageRecords
|
|
2162
|
+
totalDamage: (damageRecords?.totalDamage || 0) + damageValue,
|
|
2163
|
+
attackCount: damageRecords?.attackCount || 0,
|
|
2140
2164
|
bossGroupId: 4
|
|
2141
2165
|
}], ["handle"]);
|
|
2142
2166
|
});
|
|
2143
2167
|
return {
|
|
2144
2168
|
success: true,
|
|
2145
|
-
message:
|
|
2169
|
+
message: `成功引爆 ${itemName},造成 ${damageValue} 点伤害,获得等额金币`
|
|
2146
2170
|
};
|
|
2147
2171
|
}
|
|
2148
2172
|
if (itemConfig2.id === 2) {
|
|
@@ -2206,7 +2230,7 @@ function apply(ctx, config) {
|
|
|
2206
2230
|
}
|
|
2207
2231
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2208
2232
|
if (signInfo?.totalRewards < actualCost) {
|
|
2209
|
-
const originalHint = careerData.career === "情报副官" ?
|
|
2233
|
+
const originalHint = careerData.career === "情报副官" ? `(原价${levelData.cost})` : "";
|
|
2210
2234
|
return `❌ 需要 ${actualCost} 金币${originalHint},当前持有:${signInfo?.totalRewards || 0}`;
|
|
2211
2235
|
}
|
|
2212
2236
|
await ctx.database.withTransaction(async () => {
|
|
@@ -2219,9 +2243,11 @@ function apply(ctx, config) {
|
|
|
2219
2243
|
level: nextLevel
|
|
2220
2244
|
}], ["handle", "techId"]);
|
|
2221
2245
|
});
|
|
2222
|
-
const
|
|
2246
|
+
const costLine = careerData.career === "情报副官" ? `💰 花费金币: ${actualCost}(原价${levelData.cost})` : `💰 花费金币: ${actualCost}`;
|
|
2247
|
+
const discountHint = careerData.career === "情报副官" ? `📉 情报副官职业加成:20%折扣
|
|
2248
|
+
` : "";
|
|
2223
2249
|
return `✅ ${tech.techname} 升级至 Lv.${nextLevel}
|
|
2224
|
-
|
|
2250
|
+
${discountHint}${costLine}
|
|
2225
2251
|
📝 ${levelData.description}
|
|
2226
2252
|
💼 ${levelData.careerBonus}`;
|
|
2227
2253
|
}
|
|
@@ -2232,36 +2258,42 @@ function apply(ctx, config) {
|
|
|
2232
2258
|
handle,
|
|
2233
2259
|
weaponId: weaponData.id
|
|
2234
2260
|
});
|
|
2235
|
-
if (!equipment) return "❌
|
|
2236
|
-
if (equipment.level >= 6) return "❌
|
|
2261
|
+
if (!equipment) return "❌ 您尚未获得该武器";
|
|
2262
|
+
if (equipment.level >= 6) return "❌ 该武器已达最高等级";
|
|
2237
2263
|
const BASE_COST = [1050, 1450, 1850, 2250, 2650, 3050];
|
|
2238
2264
|
const baseCost = BASE_COST[equipment.level];
|
|
2239
2265
|
const weaponTechConfig = Spacestationtechnology.find((t) => t.techId === 2);
|
|
2240
2266
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
2241
|
-
let
|
|
2242
|
-
let
|
|
2243
|
-
|
|
2244
|
-
let baseDiscount;
|
|
2245
|
-
let careerDiscount;
|
|
2267
|
+
let techLevel = 0;
|
|
2268
|
+
let totalDiscount = 0;
|
|
2269
|
+
const discountDetails = [];
|
|
2246
2270
|
if (careerData?.group === "人类联盟") {
|
|
2247
2271
|
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 }).catch(() => [{ level: 0 }]);
|
|
2248
2272
|
techLevel = Math.min(Math.max(weaponTech?.level || 0, 0), 5);
|
|
2249
2273
|
const isCareerMatch = weaponTechConfig?.careerNames.includes(careerData?.career);
|
|
2250
2274
|
const BASE_DISCOUNTS = [5, 10, 15, 20, 25];
|
|
2251
2275
|
const CAREER_DISCOUNTS = [10, 20, 30, 40, 50];
|
|
2252
|
-
baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
|
|
2253
|
-
careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
|
|
2254
|
-
weaponDiscount = Math.max(baseDiscount, careerDiscount)
|
|
2255
|
-
|
|
2276
|
+
const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
|
|
2277
|
+
const careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
|
|
2278
|
+
const weaponDiscount = Math.max(baseDiscount, careerDiscount);
|
|
2279
|
+
if (weaponDiscount > 0) {
|
|
2280
|
+
totalDiscount += weaponDiscount;
|
|
2281
|
+
discountDetails.push(
|
|
2282
|
+
`武器系统 Lv${techLevel}${isCareerMatch ? "(科技职业加成)" : ""}:${weaponDiscount}%)`
|
|
2283
|
+
);
|
|
2284
|
+
}
|
|
2256
2285
|
}
|
|
2257
2286
|
const activeWish = await checkFoxBlessing(handle);
|
|
2258
2287
|
if (activeWish) {
|
|
2259
|
-
|
|
2288
|
+
totalDiscount += 20;
|
|
2289
|
+
discountDetails.push("灵狐升运祈愿生效:20%");
|
|
2260
2290
|
}
|
|
2291
|
+
totalDiscount = Math.min(totalDiscount, 100);
|
|
2292
|
+
const discountedCost = baseCost * (100 - totalDiscount) / 100;
|
|
2261
2293
|
const actualCost = Math.floor(discountedCost);
|
|
2262
2294
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2263
2295
|
if (signInfo?.totalRewards < actualCost) {
|
|
2264
|
-
return `❌ 需要 ${actualCost}
|
|
2296
|
+
return `❌ 需要 ${actualCost} 金币(原价${baseCost}),当前持有:${signInfo?.totalRewards || 0}`;
|
|
2265
2297
|
}
|
|
2266
2298
|
await ctx.database.withTransaction(async () => {
|
|
2267
2299
|
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
@@ -2286,20 +2318,14 @@ function apply(ctx, config) {
|
|
|
2286
2318
|
const newLevel = equipment.level + 1;
|
|
2287
2319
|
const damage = (weaponData.damage * (1 + 0.1 * newLevel)).toFixed(1);
|
|
2288
2320
|
let msg = `${target} 升级成功!Lv.${newLevel}`;
|
|
2289
|
-
const priceInfo =
|
|
2290
|
-
💸 消耗:${actualCost}
|
|
2291
|
-
💸 消耗:${actualCost}
|
|
2321
|
+
const priceInfo = totalDiscount > 0 ? `
|
|
2322
|
+
💸 消耗:${actualCost}金币 (原价${baseCost})` : `
|
|
2323
|
+
💸 消耗:${actualCost}金币`;
|
|
2292
2324
|
msg += priceInfo;
|
|
2293
|
-
let discountDetails = [];
|
|
2294
|
-
if (weaponDiscount > 0) {
|
|
2295
|
-
discountDetails.push(`${Math.round(weaponDiscount * 100)}% (武器系统 Lv${techLevel})`);
|
|
2296
|
-
}
|
|
2297
|
-
if (activeWish) {
|
|
2298
|
-
discountDetails.push("20% (灵狐升运祈愿生效)");
|
|
2299
|
-
}
|
|
2300
2325
|
if (discountDetails.length > 0) {
|
|
2301
2326
|
msg += `
|
|
2302
|
-
🔧
|
|
2327
|
+
🔧 折扣:
|
|
2328
|
+
${discountDetails.join("\n▸ ")}`;
|
|
2303
2329
|
}
|
|
2304
2330
|
msg += `
|
|
2305
2331
|
💥 伤害:${damage}`;
|
|
@@ -2338,14 +2364,11 @@ function apply(ctx, config) {
|
|
|
2338
2364
|
const level = `${index}→${index + 1}`;
|
|
2339
2365
|
let finalPrice = baseCost;
|
|
2340
2366
|
if (hasTechDiscount || hasFoxDiscount) {
|
|
2341
|
-
let
|
|
2342
|
-
if (hasTechDiscount)
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
discounted *= 0.8;
|
|
2347
|
-
}
|
|
2348
|
-
finalPrice = Math.floor(discounted);
|
|
2367
|
+
let totalDiscount = 0;
|
|
2368
|
+
if (hasTechDiscount) totalDiscount += techDiscountRate;
|
|
2369
|
+
if (hasFoxDiscount) totalDiscount += foxDiscount;
|
|
2370
|
+
totalDiscount = Math.min(totalDiscount, 100);
|
|
2371
|
+
finalPrice = Math.floor(baseCost * (1 - totalDiscount / 100));
|
|
2349
2372
|
}
|
|
2350
2373
|
const showOriginal = finalPrice < baseCost;
|
|
2351
2374
|
return [
|
|
@@ -2358,7 +2381,7 @@ function apply(ctx, config) {
|
|
|
2358
2381
|
discountNotice.push(`🔧 武器系统 Lv${techLevel} (${techDiscountRate}% 折扣)`);
|
|
2359
2382
|
}
|
|
2360
2383
|
if (hasFoxDiscount) {
|
|
2361
|
-
discountNotice.push("🦊
|
|
2384
|
+
discountNotice.push("🦊 灵狐升运祈愿 (20% 折扣)");
|
|
2362
2385
|
}
|
|
2363
2386
|
if (!hasTechDiscount && !hasFoxDiscount) {
|
|
2364
2387
|
discountNotice.push("💡 提示:加入人类联盟并升级武器系统可获得折扣");
|
|
@@ -2390,27 +2413,38 @@ function apply(ctx, config) {
|
|
|
2390
2413
|
return total;
|
|
2391
2414
|
}
|
|
2392
2415
|
__name(calculateTotalPower, "calculateTotalPower");
|
|
2416
|
+
function getBossMaxHP(bossName) {
|
|
2417
|
+
for (const bossGroup of bossPool) {
|
|
2418
|
+
if (bossGroup.main.name === bossName) {
|
|
2419
|
+
return bossGroup.main.maxHP;
|
|
2420
|
+
}
|
|
2421
|
+
for (const minion of bossGroup.minions) {
|
|
2422
|
+
if (minion.name === bossName) {
|
|
2423
|
+
return minion.maxHP;
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
return 0;
|
|
2428
|
+
}
|
|
2429
|
+
__name(getBossMaxHP, "getBossMaxHP");
|
|
2393
2430
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
2394
2431
|
const session = argv.session;
|
|
2395
2432
|
let winCount = 0;
|
|
2396
2433
|
let hiddenWinCount = 0;
|
|
2397
2434
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2398
2435
|
if (!profile) {
|
|
2399
|
-
return "🔒
|
|
2436
|
+
return "🔒 需要先绑定游戏句柄";
|
|
2400
2437
|
}
|
|
2401
2438
|
const { regionId, realmId, profileId } = profile;
|
|
2402
2439
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2403
2440
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2404
2441
|
if (existingEntries.length > 0) {
|
|
2405
|
-
return
|
|
2442
|
+
return `⛔ 您已被列入黑名单`;
|
|
2406
2443
|
}
|
|
2407
2444
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
2408
|
-
|
|
2409
|
-
return "您还没有签到。";
|
|
2410
|
-
}
|
|
2411
|
-
const quantity = backpack.quantity;
|
|
2445
|
+
const quantity = backpack?.quantity;
|
|
2412
2446
|
if (quantity < 1) {
|
|
2413
|
-
return "
|
|
2447
|
+
return "您背包中的咕咕币不足";
|
|
2414
2448
|
}
|
|
2415
2449
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2416
2450
|
handle,
|
|
@@ -2435,20 +2469,17 @@ function apply(ctx, config) {
|
|
|
2435
2469
|
const session = argv.session;
|
|
2436
2470
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2437
2471
|
if (!profile) {
|
|
2438
|
-
return "🔒
|
|
2472
|
+
return "🔒 需要先绑定游戏句柄";
|
|
2439
2473
|
}
|
|
2440
2474
|
const { regionId, realmId, profileId } = profile;
|
|
2441
2475
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2442
2476
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2443
2477
|
if (existingEntries.length > 0) {
|
|
2444
|
-
return
|
|
2478
|
+
return `⛔ 您已被列入黑名单`;
|
|
2445
2479
|
}
|
|
2446
2480
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
2447
|
-
if (
|
|
2448
|
-
return "
|
|
2449
|
-
}
|
|
2450
|
-
if (backpack.quantity < 1) {
|
|
2451
|
-
return "您的咕咕币不足。";
|
|
2481
|
+
if (backpack?.quantity < 1) {
|
|
2482
|
+
return "您背包中的咕咕币不足";
|
|
2452
2483
|
}
|
|
2453
2484
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2454
2485
|
handle,
|
|
@@ -2468,20 +2499,17 @@ function apply(ctx, config) {
|
|
|
2468
2499
|
let hiddenWinCount = 0;
|
|
2469
2500
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2470
2501
|
if (!profile) {
|
|
2471
|
-
return "🔒
|
|
2502
|
+
return "🔒 需要先绑定游戏句柄";
|
|
2472
2503
|
}
|
|
2473
2504
|
const { regionId, realmId, profileId } = profile;
|
|
2474
2505
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2475
2506
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2476
2507
|
if (existingEntries.length > 0) {
|
|
2477
|
-
return
|
|
2508
|
+
return `⛔ 您已被列入黑名单`;
|
|
2478
2509
|
}
|
|
2479
2510
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
2480
|
-
if (
|
|
2481
|
-
return "
|
|
2482
|
-
}
|
|
2483
|
-
if (backpack.quantity < 10) {
|
|
2484
|
-
return "您的咕咕币不足。";
|
|
2511
|
+
if (backpack?.quantity < 10) {
|
|
2512
|
+
return "您背包中的咕咕币不足";
|
|
2485
2513
|
}
|
|
2486
2514
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2487
2515
|
handle,
|
|
@@ -2497,35 +2525,19 @@ function apply(ctx, config) {
|
|
|
2497
2525
|
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
2498
2526
|
return [
|
|
2499
2527
|
"十连抽结果:",
|
|
2500
|
-
...results.map((r) => r ? "
|
|
2528
|
+
...results.map((r) => r ? "🎉 获得兑换券" : "❌ 未中奖"),
|
|
2501
2529
|
`保底进度:${record.pityCounter}/90`,
|
|
2502
2530
|
...hiddenWinCount > 0 ? [`🎉 恭喜你抽中隐藏奖励,额外获得 ${hiddenWinCount} 张兑换券和 ${hiddenWinCount} 枚扭蛋币!`] : []
|
|
2503
2531
|
].join("\n");
|
|
2504
2532
|
});
|
|
2505
|
-
ctx.command("ggcevo/抽奖记录").action(async (argv) => {
|
|
2506
|
-
const session = argv.session;
|
|
2507
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2508
|
-
if (!profile) {
|
|
2509
|
-
return "🔒 需要先绑定游戏句柄。";
|
|
2510
|
-
}
|
|
2511
|
-
const { regionId, realmId, profileId } = profile;
|
|
2512
|
-
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2513
|
-
const [record] = await ctx.database.get("ggcevo_records", { handle });
|
|
2514
|
-
return record ? [
|
|
2515
|
-
`总抽数:${record.totalPulls}`,
|
|
2516
|
-
`下次保底剩余:${90 - record.pityCounter}抽`,
|
|
2517
|
-
`已保底次数:${record.fullPityCount}`,
|
|
2518
|
-
...record.hiddenawards ? [`抽中隐藏奖励次数:${record.hiddenawards}`] : []
|
|
2519
|
-
].join("\n") : "您还没有进行过抽奖";
|
|
2520
|
-
});
|
|
2521
2533
|
ctx.command("ggcevo/背包").action(async (argv) => {
|
|
2522
2534
|
const session = argv.session;
|
|
2523
2535
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2524
|
-
if (!profile) return "🔒
|
|
2536
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2525
2537
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2526
2538
|
const items = await ctx.database.get("ggcevo_backpack", { handle });
|
|
2527
2539
|
const validItems = items.filter((item) => item.quantity > 0);
|
|
2528
|
-
if (!validItems.length) return "
|
|
2540
|
+
if (!validItems.length) return "您的背包空空如也。";
|
|
2529
2541
|
const itemDetails = validItems.map((userItem) => {
|
|
2530
2542
|
const entry = Object.entries(initDefaultItems).find(
|
|
2531
2543
|
([, item]) => item.id === userItem.itemId
|
|
@@ -2542,11 +2554,11 @@ ${itemDetails.join("\n")}`;
|
|
|
2542
2554
|
const session = argv.session;
|
|
2543
2555
|
let latestTime;
|
|
2544
2556
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2545
|
-
if (!profile) return "🔒
|
|
2557
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2546
2558
|
const { regionId, realmId, profileId } = profile;
|
|
2547
2559
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2548
2560
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2549
|
-
if (existingEntries.length > 0) return "
|
|
2561
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
2550
2562
|
const now = /* @__PURE__ */ new Date();
|
|
2551
2563
|
const currentChinaTime = convertUTCtoChinaTime(now);
|
|
2552
2564
|
if (config.signrequire) {
|
|
@@ -2564,7 +2576,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2564
2576
|
} else {
|
|
2565
2577
|
latestTime = currentChinaTime;
|
|
2566
2578
|
}
|
|
2567
|
-
if (!latestTime) return "
|
|
2579
|
+
if (!latestTime) return "请游玩过“咕咕虫-evolved”后签到。";
|
|
2568
2580
|
const targetDateChina = new Date(latestTime);
|
|
2569
2581
|
targetDateChina.setUTCDate(targetDateChina.getUTCDate() + 1);
|
|
2570
2582
|
if (!isSameDate(latestTime, currentChinaTime) && !isSameDate(targetDateChina, currentChinaTime)) {
|
|
@@ -2587,15 +2599,10 @@ ${itemDetails.join("\n")}`;
|
|
|
2587
2599
|
monthlyDays = record.monthlyDays + 1;
|
|
2588
2600
|
}
|
|
2589
2601
|
}
|
|
2590
|
-
const
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
startTime: { $lte: now },
|
|
2594
|
-
endTime: { $gte: now },
|
|
2595
|
-
isused: false
|
|
2596
|
-
});
|
|
2602
|
+
const messages = [];
|
|
2603
|
+
let totalBonus = 0;
|
|
2604
|
+
let basePoints;
|
|
2597
2605
|
let tickets = 3;
|
|
2598
|
-
let points = getRandomInt(20, 40);
|
|
2599
2606
|
if (monthlyDays === 7) {
|
|
2600
2607
|
tickets = 4;
|
|
2601
2608
|
} else if (monthlyDays === 14) {
|
|
@@ -2605,62 +2612,61 @@ ${itemDetails.join("\n")}`;
|
|
|
2605
2612
|
} else if (monthlyDays === 28) {
|
|
2606
2613
|
tickets = 7;
|
|
2607
2614
|
}
|
|
2608
|
-
if (monthlyDays
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
points = getRandomInt(80, 100);
|
|
2614
|
-
} else if (monthlyDays >= 28) {
|
|
2615
|
-
points = getRandomInt(100, 200);
|
|
2616
|
-
}
|
|
2617
|
-
let redCrystal = 0;
|
|
2618
|
-
let effectMessage = "";
|
|
2619
|
-
let bonusMessage = "";
|
|
2620
|
-
let careerCrystalMessage = "";
|
|
2621
|
-
let cred17Message = "";
|
|
2622
|
-
let allianceBonusMessage = "";
|
|
2615
|
+
if (monthlyDays < 7) basePoints = getRandomInt(20, 40);
|
|
2616
|
+
else if (monthlyDays < 14) basePoints = getRandomInt(40, 60);
|
|
2617
|
+
else if (monthlyDays < 21) basePoints = getRandomInt(60, 80);
|
|
2618
|
+
else if (monthlyDays < 28) basePoints = getRandomInt(80, 100);
|
|
2619
|
+
else basePoints = getRandomInt(100, 200);
|
|
2623
2620
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
2624
2621
|
if (careerData?.group === "人类联盟") {
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
let miningBonus = 0;
|
|
2630
|
-
let miningMessage = "";
|
|
2631
|
-
const BASE_BONUS = [5, 10, 15, 20, 25];
|
|
2632
|
-
const CAREER_BONUS = [10, 20, 30, 40, 50];
|
|
2622
|
+
totalBonus += 0.2;
|
|
2623
|
+
messages.push("🏛️ 人类联盟阵营加成:金币+20%");
|
|
2624
|
+
const [userMiningTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 1 }).catch(() => [{ level: 0 }]);
|
|
2625
|
+
const techLevel = Math.min(userMiningTech?.level || 0, 5);
|
|
2633
2626
|
const miningTechConfig = Spacestationtechnology.find((t) => t.techId === 1);
|
|
2634
2627
|
if (miningTechConfig) {
|
|
2635
|
-
const
|
|
2636
|
-
|
|
2637
|
-
techId: 1
|
|
2638
|
-
}).catch(() => [{ level: 0 }]);
|
|
2639
|
-
const techLevel = Math.min(Math.max(userMiningTech?.level || 0, 0), 5);
|
|
2640
|
-
const baseBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
|
|
2628
|
+
const BASE_BONUS = [5, 10, 15, 20, 25];
|
|
2629
|
+
const baseTechBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
|
|
2641
2630
|
let careerTechBonus = 0;
|
|
2642
|
-
if (careerData
|
|
2631
|
+
if (careerData.career && miningTechConfig.careerNames.includes(careerData.career)) {
|
|
2632
|
+
const CAREER_BONUS = [10, 20, 30, 40, 50];
|
|
2643
2633
|
careerTechBonus = techLevel > 0 ? CAREER_BONUS[techLevel - 1] : 0;
|
|
2644
2634
|
}
|
|
2645
|
-
|
|
2646
|
-
if (
|
|
2647
|
-
|
|
2648
|
-
|
|
2635
|
+
const finalBonus = Math.max(baseTechBonus, careerTechBonus);
|
|
2636
|
+
if (finalBonus > 0) {
|
|
2637
|
+
totalBonus += finalBonus / 100;
|
|
2638
|
+
messages.push(`⚙️ 采掘系统 Lv${techLevel} 加成:金币+${finalBonus}%`);
|
|
2649
2639
|
}
|
|
2650
2640
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
minerBonus = 50;
|
|
2655
|
-
minerMessage = `
|
|
2656
|
-
⛏️ 深空矿工职业加成:金币+50%`;
|
|
2641
|
+
if (careerData.career === "深空矿工") {
|
|
2642
|
+
totalBonus += 0.5;
|
|
2643
|
+
messages.push("⛏️ 深空矿工职业加成:金币+50%");
|
|
2657
2644
|
}
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2645
|
+
}
|
|
2646
|
+
if (careerData?.group === "辛迪加海盗") {
|
|
2647
|
+
const [cred17Item] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: 3 });
|
|
2648
|
+
if (cred17Item?.quantity >= 1) {
|
|
2649
|
+
const currentGold = record?.totalRewards || 0;
|
|
2650
|
+
const additional = Math.min(Math.floor(currentGold / 100), 100);
|
|
2651
|
+
const credBonus = 0.5 + additional / 100;
|
|
2652
|
+
totalBonus += credBonus;
|
|
2653
|
+
messages.push(`💎 CRED-17生效:金币+50% 额外+${additional}%`);
|
|
2661
2654
|
}
|
|
2662
|
-
bonusMessage = miningMessage + minerMessage;
|
|
2663
2655
|
}
|
|
2656
|
+
const [meowEffect] = await ctx.database.get("ggcevo_Wish_Record", {
|
|
2657
|
+
handle,
|
|
2658
|
+
wishname: "喵喵财源",
|
|
2659
|
+
startTime: { $lte: now },
|
|
2660
|
+
endTime: { $gte: now },
|
|
2661
|
+
isused: false
|
|
2662
|
+
});
|
|
2663
|
+
if (meowEffect) {
|
|
2664
|
+
tickets *= 2;
|
|
2665
|
+
totalBonus += 1;
|
|
2666
|
+
messages.push("🐾 喵喵财源祈愿生效:咕咕币×2,金币+100%");
|
|
2667
|
+
}
|
|
2668
|
+
const finalPoints = Math.round(basePoints * (1 + totalBonus));
|
|
2669
|
+
let redCrystal = 0;
|
|
2664
2670
|
if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
|
|
2665
2671
|
if (monthlyDays < 7) {
|
|
2666
2672
|
redCrystal = 1;
|
|
@@ -2673,32 +2679,14 @@ ${itemDetails.join("\n")}`;
|
|
|
2673
2679
|
} else {
|
|
2674
2680
|
redCrystal = 5;
|
|
2675
2681
|
}
|
|
2676
|
-
|
|
2677
|
-
⚓ 辛迪加财务经理职业加成:获得 ${redCrystal} 红晶`;
|
|
2678
|
-
}
|
|
2679
|
-
if (careerData?.group === "辛迪加海盗") {
|
|
2680
|
-
const [cred17Item] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: 3 });
|
|
2681
|
-
if (cred17Item?.quantity >= 1) {
|
|
2682
|
-
const currentGold = record?.totalRewards || 0;
|
|
2683
|
-
const additionalBonus = Math.min(Math.floor(currentGold / 100), 100);
|
|
2684
|
-
const totalBonus = 0.5 + additionalBonus * 0.01;
|
|
2685
|
-
points = Math.round(points * (1 + totalBonus));
|
|
2686
|
-
cred17Message = `
|
|
2687
|
-
💎 CRED-17生效:签到奖励+50%,当前金币${currentGold}(+${additionalBonus}%),总计加成+${(totalBonus * 100).toFixed(0)}%`;
|
|
2688
|
-
}
|
|
2682
|
+
messages.push(`⚓ 辛迪加财务经理职业加成:获得${redCrystal}枚红晶`);
|
|
2689
2683
|
}
|
|
2690
|
-
if (meowEffect) {
|
|
2691
|
-
tickets *= 2;
|
|
2692
|
-
points *= 2;
|
|
2693
|
-
effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励(金币和咕咕币)!";
|
|
2694
|
-
}
|
|
2695
|
-
effectMessage += cred17Message;
|
|
2696
2684
|
await ctx.database.withTransaction(async () => {
|
|
2697
2685
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
2698
2686
|
handle,
|
|
2699
2687
|
lastSign: now,
|
|
2700
2688
|
monthlyDays,
|
|
2701
|
-
totalRewards: (record?.totalRewards || 0) +
|
|
2689
|
+
totalRewards: (record?.totalRewards || 0) + finalPoints
|
|
2702
2690
|
}]);
|
|
2703
2691
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2704
2692
|
handle,
|
|
@@ -2712,9 +2700,15 @@ ${itemDetails.join("\n")}`;
|
|
|
2712
2700
|
}], ["handle"]);
|
|
2713
2701
|
}
|
|
2714
2702
|
});
|
|
2703
|
+
let effectMessage = "";
|
|
2704
|
+
if (messages.length > 0) {
|
|
2705
|
+
effectMessage = `
|
|
2706
|
+
⚡ 加成效果:
|
|
2707
|
+
▸ ${messages.join("\n▸ ")}`;
|
|
2708
|
+
}
|
|
2715
2709
|
return `签到成功!本月累计签到${monthlyDays}天,获得:
|
|
2716
|
-
💰 金币 x ${
|
|
2717
|
-
🪙 咕咕币 x ${tickets}
|
|
2710
|
+
💰 金币 x ${finalPoints}${totalBonus > 0 ? `(基础值 ${basePoints})` : ""}
|
|
2711
|
+
🪙 咕咕币 x ${tickets}${effectMessage}`;
|
|
2718
2712
|
} catch (error) {
|
|
2719
2713
|
console.error("签到命令时发生错误:", error);
|
|
2720
2714
|
return "服务器繁忙,请稍后尝试。";
|
|
@@ -2724,13 +2718,13 @@ ${itemDetails.join("\n")}`;
|
|
|
2724
2718
|
try {
|
|
2725
2719
|
const session = argv.session;
|
|
2726
2720
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2727
|
-
if (!profile) return "🔒
|
|
2721
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2728
2722
|
const { regionId, realmId, profileId } = profile;
|
|
2729
2723
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2730
2724
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2731
|
-
if (existingEntries.length > 0) return "
|
|
2725
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
2732
2726
|
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2733
|
-
if (!record) return "
|
|
2727
|
+
if (!record) return "暂未查询到您的签到记录";
|
|
2734
2728
|
const lastSignChina = convertUTCtoChinaTime(record.lastSign);
|
|
2735
2729
|
const targetDateChina = new Date(lastSignChina);
|
|
2736
2730
|
const nowChina = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
@@ -2739,7 +2733,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2739
2733
|
const yesterday = new Date(targetDateChina).getUTCDate() - 1;
|
|
2740
2734
|
if (targetDateChina.getUTCFullYear() !== currentYear || targetDateChina.getUTCMonth() !== currentMonth || // 必须当月
|
|
2741
2735
|
record.monthlyDays > yesterday) {
|
|
2742
|
-
return "
|
|
2736
|
+
return "暂时没有可补签的日期";
|
|
2743
2737
|
}
|
|
2744
2738
|
const costPoints = 100;
|
|
2745
2739
|
if (record.totalRewards < costPoints) {
|
|
@@ -2776,46 +2770,16 @@ ${itemDetails.join("\n")}`;
|
|
|
2776
2770
|
return "补签失败,请稍后重试。";
|
|
2777
2771
|
}
|
|
2778
2772
|
});
|
|
2779
|
-
ctx.command("ggcevo/签到记录").action(async (argv) => {
|
|
2780
|
-
const session = argv.session;
|
|
2781
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2782
|
-
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2783
|
-
const { regionId, realmId, profileId } = profile;
|
|
2784
|
-
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2785
|
-
const [record] = await ctx.database.get("ggcevo_sign", { handle });
|
|
2786
|
-
if (!record) return "您还没有签到。";
|
|
2787
|
-
const chinaTime = record.lastSign.toLocaleString("zh-CN", {
|
|
2788
|
-
timeZone: "Asia/Shanghai",
|
|
2789
|
-
year: "numeric",
|
|
2790
|
-
month: "2-digit",
|
|
2791
|
-
day: "2-digit",
|
|
2792
|
-
hour: "2-digit",
|
|
2793
|
-
minute: "2-digit",
|
|
2794
|
-
second: "2-digit",
|
|
2795
|
-
hour12: false
|
|
2796
|
-
});
|
|
2797
|
-
return [
|
|
2798
|
-
`您的句柄:${handle}`,
|
|
2799
|
-
`📅 最后签到时间:${chinaTime}`,
|
|
2800
|
-
`🔥 累计签到:${record.monthlyDays}天`,
|
|
2801
|
-
`💰 拥有金币:${record.totalRewards}枚金币`
|
|
2802
|
-
].join("\n");
|
|
2803
|
-
});
|
|
2804
2773
|
ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
|
|
2805
2774
|
const session = argv.session;
|
|
2806
2775
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2807
|
-
if (!profile) return "🔒
|
|
2776
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2808
2777
|
const { regionId, realmId, profileId } = profile;
|
|
2809
2778
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
2810
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2811
|
-
if (existingEntries.length > 0) {
|
|
2812
|
-
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
2813
|
-
}
|
|
2814
2779
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 1 });
|
|
2815
|
-
if (!backpack) return "您还没有签到。";
|
|
2816
2780
|
const memberInfo = await session.event?.member?.roles;
|
|
2817
2781
|
if (memberInfo?.includes("member")) {
|
|
2818
|
-
return "❌
|
|
2782
|
+
return "❌ 仅限管理员和群主领取每月津贴";
|
|
2819
2783
|
}
|
|
2820
2784
|
const now = /* @__PURE__ */ new Date();
|
|
2821
2785
|
const chinatime = convertUTCtoChinaTime(now);
|
|
@@ -2842,26 +2806,26 @@ ${itemDetails.join("\n")}`;
|
|
|
2842
2806
|
await ctx.database.upsert("ggcevo_backpack", [{
|
|
2843
2807
|
handle,
|
|
2844
2808
|
itemId: 1,
|
|
2845
|
-
quantity: (backpack
|
|
2809
|
+
quantity: (backpack?.quantity || 0) + 50
|
|
2846
2810
|
}]);
|
|
2847
2811
|
return `[管理专属] 成功领取本月津贴,获得了50枚咕咕币!`;
|
|
2848
2812
|
});
|
|
2849
2813
|
ctx.command("ggcevo/领取 [name]").action(async (argv, name2) => {
|
|
2850
2814
|
const session = argv.session;
|
|
2815
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2816
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2817
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2818
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2819
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
2851
2820
|
if (!name2) {
|
|
2852
|
-
await session.send("请在30
|
|
2821
|
+
await session.send("请在30秒内输入活动名称:");
|
|
2853
2822
|
name2 = await session.prompt(3e4);
|
|
2854
|
-
if (!name2) return "
|
|
2823
|
+
if (!name2) return "已取消操作,请重新输入。";
|
|
2855
2824
|
}
|
|
2856
2825
|
const itemIdToName = {};
|
|
2857
2826
|
for (const [name3, item] of Object.entries(initDefaultItems)) {
|
|
2858
2827
|
itemIdToName[item.id] = name3;
|
|
2859
2828
|
}
|
|
2860
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2861
|
-
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
2862
|
-
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
2863
|
-
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
2864
|
-
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
2865
2829
|
const [activity] = await ctx.database.get("ggcevo_activity", {
|
|
2866
2830
|
name: name2,
|
|
2867
2831
|
status: "进行中"
|
|
@@ -2931,7 +2895,9 @@ ${itemDetails.join("\n")}`;
|
|
|
2931
2895
|
});
|
|
2932
2896
|
return `活动【${activityName}】创建成功!奖励内容:${itemName} x${quantity}。`;
|
|
2933
2897
|
});
|
|
2934
|
-
ctx.command("ggcevo/活动列表").action(async () => {
|
|
2898
|
+
ctx.command("ggcevo/活动列表").action(async ({ session }) => {
|
|
2899
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
2900
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
2935
2901
|
const activities = await ctx.database.get(
|
|
2936
2902
|
"ggcevo_activity",
|
|
2937
2903
|
{ status: "进行中" },
|
|
@@ -2946,7 +2912,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2946
2912
|
`活动时间:${formatDate(a.startTime)} - ${formatDate(a.endTime)}`,
|
|
2947
2913
|
`活动描述:${a.description}`,
|
|
2948
2914
|
`活动奖励:${a.quantity} ${itemMap.get(a.itemId) || "未知物品"}`,
|
|
2949
|
-
"━".repeat(
|
|
2915
|
+
"━".repeat(14)
|
|
2950
2916
|
].join("\n")),
|
|
2951
2917
|
"请输入「领取 活动名称」领取奖励"
|
|
2952
2918
|
].join("\n") : "当前没有进行中的活动。";
|
|
@@ -3095,7 +3061,9 @@ ${itemDetails.join("\n")}`;
|
|
|
3095
3061
|
return "服务器繁忙,请稍后尝试。";
|
|
3096
3062
|
}
|
|
3097
3063
|
});
|
|
3098
|
-
ctx.command("ggcevo/胜点榜 [page]").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async (
|
|
3064
|
+
ctx.command("ggcevo/胜点榜 [page]").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
|
|
3065
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3066
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3099
3067
|
const pageNum = parseInt(page) || 1;
|
|
3100
3068
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
3101
3069
|
const offset = (pageNum - 1) * 10;
|
|
@@ -3104,7 +3072,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3104
3072
|
ctx.database.select("ggcevo_rank").where({ Blacklist: false, rankseason: config.rankseason }).execute((row) => import_koishi.$.count(row.handle))
|
|
3105
3073
|
]);
|
|
3106
3074
|
const totalPages = Math.ceil(total / 10);
|
|
3107
|
-
if (pageNum > totalPages) return
|
|
3075
|
+
if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
|
|
3108
3076
|
const processedRecords = await Promise.all(
|
|
3109
3077
|
records.map(async (item) => ({
|
|
3110
3078
|
...item,
|
|
@@ -3259,7 +3227,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3259
3227
|
if (!player) {
|
|
3260
3228
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3261
3229
|
if (!profile) {
|
|
3262
|
-
return "🔒
|
|
3230
|
+
return "🔒 需要先绑定游戏句柄";
|
|
3263
3231
|
}
|
|
3264
3232
|
const { regionId, realmId, profileId } = profile;
|
|
3265
3233
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -3287,7 +3255,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3287
3255
|
} else {
|
|
3288
3256
|
const parsedUser = import_koishi.h.parse(player)[0];
|
|
3289
3257
|
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) {
|
|
3290
|
-
return "
|
|
3258
|
+
return "参数错误,请输入“排名 @玩家”";
|
|
3291
3259
|
}
|
|
3292
3260
|
const targetUserId = parsedUser.attrs.id;
|
|
3293
3261
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
@@ -3323,7 +3291,7 @@ ${itemDetails.join("\n")}`;
|
|
|
3323
3291
|
ctx.command("ggcevo/给予 <handle> <itemName:string> <amount:number>", "增加用户物品/金币", { authority: 3 }).action(async (_, handle, itemName, amount) => {
|
|
3324
3292
|
try {
|
|
3325
3293
|
if (!handle || !itemName || amount <= 0) {
|
|
3326
|
-
return "参数格式错误,正确格式:给予
|
|
3294
|
+
return "参数格式错误,正确格式:给予 句柄 物品名称 数量";
|
|
3327
3295
|
}
|
|
3328
3296
|
const parsedAmount = Math.floor(amount);
|
|
3329
3297
|
if (itemName === "金币") {
|
|
@@ -3368,19 +3336,19 @@ ${itemDetails.join("\n")}`;
|
|
|
3368
3336
|
return "操作失败:" + (err instanceof Error ? err.message : "数据库异常");
|
|
3369
3337
|
}
|
|
3370
3338
|
});
|
|
3371
|
-
ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [
|
|
3339
|
+
ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@玩家] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
|
|
3372
3340
|
const session = argv.session;
|
|
3373
3341
|
const pageNum = argv.options.p ? argv.options.p : 1;
|
|
3374
3342
|
const user = argv.args[0];
|
|
3375
3343
|
let handle;
|
|
3376
3344
|
if (!user) {
|
|
3377
3345
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3378
|
-
if (!profile) return "🔒
|
|
3346
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3379
3347
|
handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3380
3348
|
} else {
|
|
3381
3349
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
3382
3350
|
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) {
|
|
3383
|
-
return "
|
|
3351
|
+
return "参数错误,请输入“违规记录 @玩家”";
|
|
3384
3352
|
}
|
|
3385
3353
|
const targetUserId = parsedUser.attrs.id;
|
|
3386
3354
|
let targetUsername = parsedUser.attrs.name || targetUserId;
|
|
@@ -3418,17 +3386,17 @@ ${itemDetails.join("\n")}`;
|
|
|
3418
3386
|
"------------------------------",
|
|
3419
3387
|
recordText,
|
|
3420
3388
|
"------------------------------",
|
|
3421
|
-
pageNum < totalPages ? `输入 违规记录 (
|
|
3389
|
+
pageNum < totalPages ? `输入 违规记录 (@玩家) -p ${pageNum + 1} 查看下一条` : "已是最后一页"
|
|
3422
3390
|
].join("\n");
|
|
3423
3391
|
});
|
|
3424
3392
|
ctx.command("ggcevo/兑换", "兑换物品").action(async ({ session }) => {
|
|
3425
3393
|
try {
|
|
3426
3394
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3427
|
-
if (!profile) return "🔒
|
|
3395
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3428
3396
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3429
3397
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3430
3398
|
if (existingEntries.length > 0) {
|
|
3431
|
-
return
|
|
3399
|
+
return `⛔ 您已被列入黑名单`;
|
|
3432
3400
|
}
|
|
3433
3401
|
const currentSeason = config.rankseason;
|
|
3434
3402
|
const qualityGroups = {};
|
|
@@ -3472,7 +3440,7 @@ ${items.join("、")}
|
|
|
3472
3440
|
}
|
|
3473
3441
|
await session.send(message);
|
|
3474
3442
|
const name2 = await session.prompt(3e4);
|
|
3475
|
-
if (!name2) return "
|
|
3443
|
+
if (!name2) return "已取消操作,请重新输入。";
|
|
3476
3444
|
const configname = itemConfig[name2];
|
|
3477
3445
|
if (!configname) return "无效的物品名称,请重新输入。";
|
|
3478
3446
|
const userRecords = await ctx.database.get("ggcevo_exchange", { handle, item: name2 });
|
|
@@ -3511,7 +3479,7 @@ ${items.join("、")}
|
|
|
3511
3479
|
if (!coupon || coupon.quantity < cost) {
|
|
3512
3480
|
const requireMsg = petItems.has(name2) ? `需要1个${configname.quality}级宠物扭蛋 或${configname.cost}张兑奖券` : `需要${configname.cost}张兑奖券`;
|
|
3513
3481
|
return `${requireMsg}
|
|
3514
|
-
|
|
3482
|
+
您当前持有:${coupon?.quantity || 0}个${couponName}`;
|
|
3515
3483
|
}
|
|
3516
3484
|
const isGlobal = configname.isLimited || config.ignoreGlobalLimit === false;
|
|
3517
3485
|
await ctx.database.withTransaction(async () => {
|
|
@@ -3532,38 +3500,19 @@ ${items.join("、")}
|
|
|
3532
3500
|
season: currentSeason
|
|
3533
3501
|
});
|
|
3534
3502
|
});
|
|
3535
|
-
return
|
|
3503
|
+
return `🎉 恭喜!您使用 ${cost} 个 ${couponName} 兑换了 【${name2}】`;
|
|
3536
3504
|
} catch (error) {
|
|
3537
3505
|
console.error("兑换失败:", error);
|
|
3538
3506
|
return "兑换失败";
|
|
3539
3507
|
}
|
|
3540
3508
|
});
|
|
3541
|
-
ctx.command("ggcevo/兑换记录").action(async ({ session }) => {
|
|
3542
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3543
|
-
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
3544
|
-
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3545
|
-
const exchanges = await ctx.database.get("ggcevo_exchange", { handle });
|
|
3546
|
-
if (!exchanges.length) return "您暂无兑换记录";
|
|
3547
|
-
const output = exchanges.map((e) => {
|
|
3548
|
-
const date = new Date(e.date);
|
|
3549
|
-
const cnTime = date.toLocaleString("zh-CN", {
|
|
3550
|
-
timeZone: "Asia/Shanghai",
|
|
3551
|
-
year: "numeric",
|
|
3552
|
-
month: "2-digit",
|
|
3553
|
-
day: "2-digit"
|
|
3554
|
-
});
|
|
3555
|
-
return `${e.type}: ${e.item} | 时间: ${cnTime}`;
|
|
3556
|
-
}).join("\n");
|
|
3557
|
-
return `${handle} 的兑换记录:
|
|
3558
|
-
${output}`;
|
|
3559
|
-
});
|
|
3560
3509
|
ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
|
|
3561
3510
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3562
|
-
if (!profile) return "🔒
|
|
3511
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3563
3512
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3564
3513
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3565
3514
|
if (existingEntries.length > 0) {
|
|
3566
|
-
return
|
|
3515
|
+
return `⛔ 您已被列入黑名单`;
|
|
3567
3516
|
}
|
|
3568
3517
|
await session.send(`您确定要使用3张兑换券换取一枚扭蛋币吗?(请在30秒内回复“是”确认)`);
|
|
3569
3518
|
const confirm = await session.prompt(3e4);
|
|
@@ -3571,7 +3520,7 @@ ${output}`;
|
|
|
3571
3520
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
3572
3521
|
const [coupon] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 2 });
|
|
3573
3522
|
if (!coupon || coupon.quantity < 3) {
|
|
3574
|
-
return `兑换扭蛋币需要3
|
|
3523
|
+
return `兑换扭蛋币需要3张兑奖券,您当前持有:${coupon?.quantity || 0}`;
|
|
3575
3524
|
}
|
|
3576
3525
|
await ctx.database.set(
|
|
3577
3526
|
"ggcevo_backpack",
|
|
@@ -3583,23 +3532,23 @@ ${output}`;
|
|
|
3583
3532
|
itemId: 3,
|
|
3584
3533
|
quantity: (backpack?.quantity || 0) + 1
|
|
3585
3534
|
}]);
|
|
3586
|
-
return
|
|
3535
|
+
return `🎉恭喜!您使用 3 张兑奖券兑换了 1 枚扭蛋币`;
|
|
3587
3536
|
});
|
|
3588
3537
|
ctx.command("ggcevo/扭蛋").action(async (argv) => {
|
|
3589
3538
|
const session = argv.session;
|
|
3590
3539
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3591
3540
|
if (!profile) {
|
|
3592
|
-
return "🔒
|
|
3541
|
+
return "🔒 需要先绑定游戏句柄";
|
|
3593
3542
|
}
|
|
3594
3543
|
const { regionId, realmId, profileId } = profile;
|
|
3595
3544
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
3596
3545
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3597
3546
|
if (existingEntries.length > 0) {
|
|
3598
|
-
return
|
|
3547
|
+
return `⛔ 您已被列入黑名单`;
|
|
3599
3548
|
}
|
|
3600
3549
|
const [backpack] = await ctx.database.get("ggcevo_backpack", { handle, itemId: 3 });
|
|
3601
3550
|
if (!backpack || backpack.quantity < 1) {
|
|
3602
|
-
return
|
|
3551
|
+
return `当前扭蛋币不足,您拥有:${backpack?.quantity || 0}枚`;
|
|
3603
3552
|
}
|
|
3604
3553
|
const awardName = PetCapsuleToy();
|
|
3605
3554
|
const awardItem = Object.entries(initDefaultItems).find(
|
|
@@ -3621,16 +3570,18 @@ ${output}`;
|
|
|
3621
3570
|
itemId: itemData.id,
|
|
3622
3571
|
quantity: currentQuantity + 1
|
|
3623
3572
|
}]);
|
|
3624
|
-
return `🎉
|
|
3573
|
+
return `🎉 恭喜!您获得了 ${itemName}`;
|
|
3625
3574
|
});
|
|
3626
|
-
ctx.command("ggcevo/拉黑", "添加用户到黑名单").action(async (argv) => {
|
|
3575
|
+
ctx.command("ggcevo/拉黑 [handle]", "添加用户到黑名单").action(async (argv, handle) => {
|
|
3627
3576
|
const session = argv.session;
|
|
3628
3577
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
3629
3578
|
return "⚠️ 没有操作权限。";
|
|
3630
3579
|
}
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3580
|
+
if (!handle) {
|
|
3581
|
+
await session.send("请在30秒内输入需要拉黑的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
3582
|
+
handle = await session.prompt(3e4);
|
|
3583
|
+
if (!handle) return "已取消操作,请重新输入。";
|
|
3584
|
+
}
|
|
3634
3585
|
try {
|
|
3635
3586
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
3636
3587
|
if (!handleRegex.test(handle)) {
|
|
@@ -3644,20 +3595,22 @@ ${output}`;
|
|
|
3644
3595
|
handle,
|
|
3645
3596
|
createdAt: /* @__PURE__ */ new Date()
|
|
3646
3597
|
});
|
|
3647
|
-
return `✅
|
|
3598
|
+
return `✅ 操作成功,用户${handle}被列入黑名单。`;
|
|
3648
3599
|
} catch (error) {
|
|
3649
3600
|
console.error("黑名单操作失败:", error);
|
|
3650
3601
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
3651
3602
|
}
|
|
3652
3603
|
});
|
|
3653
|
-
ctx.command("ggcevo/标记", "标记用户到胜点榜黑名单").action(async (argv) => {
|
|
3604
|
+
ctx.command("ggcevo/标记 [handle]", "标记用户到胜点榜黑名单").action(async (argv, handle) => {
|
|
3654
3605
|
const session = argv.session;
|
|
3655
3606
|
if (!ctx.config.admins.includes(session.userId)) {
|
|
3656
3607
|
return "⚠️ 没有操作权限。";
|
|
3657
3608
|
}
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3609
|
+
if (!handle) {
|
|
3610
|
+
await session.send("请在30秒内输入需要标记的句柄:\n(句柄格式为: [区域ID]-S2-[服务器ID]-[档案ID])");
|
|
3611
|
+
handle = await session.prompt(3e4);
|
|
3612
|
+
if (!handle) return "已取消操作,请重新输入。";
|
|
3613
|
+
}
|
|
3661
3614
|
try {
|
|
3662
3615
|
const handleRegex = /^([1235])-S2-([12])-(\d+)$/;
|
|
3663
3616
|
if (!handleRegex.test(handle)) {
|
|
@@ -3665,48 +3618,24 @@ ${output}`;
|
|
|
3665
3618
|
}
|
|
3666
3619
|
const existingEntries = await ctx.database.get("ggcevo_rank", { handle, Blacklist: true, rankseason: config.rankseason });
|
|
3667
3620
|
if (existingEntries.length > 0) {
|
|
3668
|
-
return `${handle}
|
|
3621
|
+
return `${handle}已在当前赛季胜点榜上被标记。`;
|
|
3669
3622
|
}
|
|
3670
3623
|
await ctx.database.upsert("ggcevo_rank", [{
|
|
3671
3624
|
handle,
|
|
3672
3625
|
Blacklist: true,
|
|
3673
3626
|
rankseason: config.rankseason
|
|
3674
3627
|
}]);
|
|
3675
|
-
return `✅
|
|
3628
|
+
return `✅ 操作成功,用户${handle}在当前赛季胜点榜上被标记。`;
|
|
3676
3629
|
} catch (error) {
|
|
3677
3630
|
console.error("黑名单操作失败:", error);
|
|
3678
3631
|
return "操作失败,请稍后重试。错误详情已记录";
|
|
3679
3632
|
}
|
|
3680
3633
|
});
|
|
3681
|
-
ctx.command("ggcevo/成就").action(async ({ session }) => {
|
|
3682
|
-
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3683
|
-
if (!profile) {
|
|
3684
|
-
return "🔒 需要先绑定游戏句柄。";
|
|
3685
|
-
}
|
|
3686
|
-
const { regionId, realmId, profileId } = profile;
|
|
3687
|
-
const achievements = await ctx.database.get("ggcevo_achievements", {
|
|
3688
|
-
handle: `${regionId}-S2-${realmId}-${profileId}`
|
|
3689
|
-
});
|
|
3690
|
-
if (!achievements.length) {
|
|
3691
|
-
return "你还没有获得任何成就。";
|
|
3692
|
-
}
|
|
3693
|
-
const achievementList = achievements.map((achievement) => {
|
|
3694
|
-
const date = new Date(achievement.gaintime);
|
|
3695
|
-
return `${achievement.achievementname} (获得于 ${date.toLocaleDateString("zh-CN", {
|
|
3696
|
-
timeZone: "Asia/Shanghai",
|
|
3697
|
-
year: "numeric",
|
|
3698
|
-
month: "2-digit",
|
|
3699
|
-
day: "2-digit"
|
|
3700
|
-
})})`;
|
|
3701
|
-
});
|
|
3702
|
-
return `${regionId}-S2-${realmId}-${profileId} 已获得的成就:
|
|
3703
|
-
${achievementList.join("\n")}`;
|
|
3704
|
-
});
|
|
3705
3634
|
ctx.command("ggcevo/个人信息").action(async (argv) => {
|
|
3706
3635
|
const session = argv.session;
|
|
3707
3636
|
const output = [];
|
|
3708
3637
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3709
|
-
if (!profile) return "🔒
|
|
3638
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3710
3639
|
const { regionId, realmId, profileId } = profile;
|
|
3711
3640
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
3712
3641
|
output.push(`🎮 游戏句柄:${handle}
|
|
@@ -3733,10 +3662,10 @@ ${achievementList.join("\n")}`;
|
|
|
3733
3662
|
if (lottery) {
|
|
3734
3663
|
output.push(
|
|
3735
3664
|
"🎉 抽奖统计:",
|
|
3736
|
-
|
|
3665
|
+
`总计抽奖:${lottery.totalPulls} 次`,
|
|
3737
3666
|
`距离保底剩余:${90 - lottery.pityCounter} 抽`,
|
|
3738
|
-
|
|
3739
|
-
...lottery.hiddenawards ? [
|
|
3667
|
+
`触发保底:${lottery.fullPityCount} 次`,
|
|
3668
|
+
...lottery.hiddenawards ? [`隐藏奖励:${lottery.hiddenawards} 次`] : [],
|
|
3740
3669
|
"──────────────"
|
|
3741
3670
|
);
|
|
3742
3671
|
}
|
|
@@ -3838,16 +3767,16 @@ ${achievementList.join("\n")}`;
|
|
|
3838
3767
|
ctx.command("ggcevo/pk [user]", "发起玩家对战").alias("挑战").action(async (argv, user) => {
|
|
3839
3768
|
try {
|
|
3840
3769
|
const session = argv.session;
|
|
3841
|
-
if (!user) return "请输入“pk @指定pk玩家”。";
|
|
3842
3770
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3843
|
-
if (!profile) return "🔒
|
|
3771
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
3844
3772
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3845
3773
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3846
3774
|
if (existingEntries.length > 0) {
|
|
3847
|
-
return
|
|
3775
|
+
return `⛔ 您已被列入黑名单`;
|
|
3848
3776
|
}
|
|
3777
|
+
if (!user) return "请输入“pk @玩家”。";
|
|
3849
3778
|
const parsedUser = import_koishi.h.parse(user)[0];
|
|
3850
|
-
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk
|
|
3779
|
+
if (!parsedUser || parsedUser.type !== "at" || !parsedUser.attrs.id) return "参数格式错误,请输入“pk @玩家”。";
|
|
3851
3780
|
const targetUserId = parsedUser.attrs.id;
|
|
3852
3781
|
const targetUsername = await session.bot.getGuildMember(session.guildId, targetUserId);
|
|
3853
3782
|
const [targetprofile] = await ctx.database.get("sc2arcade_player", { userId: targetUserId });
|
|
@@ -4016,7 +3945,7 @@ ${achievementList.join("\n")}`;
|
|
|
4016
3945
|
`🎰 金币变动:${stealPercentage}%`
|
|
4017
3946
|
];
|
|
4018
3947
|
isWin ? result.push(`💰 您从对方的口袋里抢夺了${goldTransfer}枚金币`) : result.push(`💸 您从口袋里拿出了${goldTransfer}枚金币上交给对方`);
|
|
4019
|
-
initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴
|
|
3948
|
+
initiatorCareer?.group === "辛迪加海盗" ? result.push(`🔴 辛迪加海盗阵营加成:获得1枚红晶`) : "";
|
|
4020
3949
|
result.push(`📅 剩余挑战次数:${config.dailyPKLimit - (initiatorPK.todayCount + 1)}`);
|
|
4021
3950
|
return result.join("\n");
|
|
4022
3951
|
} catch (error) {
|
|
@@ -4024,7 +3953,9 @@ ${achievementList.join("\n")}`;
|
|
|
4024
3953
|
return "对战功能暂时不可用,请稍后重试";
|
|
4025
3954
|
}
|
|
4026
3955
|
});
|
|
4027
|
-
ctx.command("ggcevo/pk榜 [page]", "查看玩家PK排行榜").usage("输入 pk榜 [页码] 查看对应页的排行榜,每页10条").action(async (
|
|
3956
|
+
ctx.command("ggcevo/pk榜 [page]", "查看玩家PK排行榜").usage("输入 pk榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
|
|
3957
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3958
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4028
3959
|
const pageNum = parseInt(page) || 1;
|
|
4029
3960
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
4030
3961
|
const offset = (pageNum - 1) * 10;
|
|
@@ -4035,7 +3966,7 @@ ${achievementList.join("\n")}`;
|
|
|
4035
3966
|
ctx.database.select("ggcevo_pk").where({ enable: true }).execute((row) => import_koishi.$.count(row.handle))
|
|
4036
3967
|
]);
|
|
4037
3968
|
const totalPages = Math.ceil(total / 10);
|
|
4038
|
-
if (pageNum > totalPages) return
|
|
3969
|
+
if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
|
|
4039
3970
|
if (!records.length) return "暂无PK记录";
|
|
4040
3971
|
const rankingText = records.map((record, index) => {
|
|
4041
3972
|
const winRate = record.total > 0 ? `${(record.wins / record.total * 100).toFixed(1)}%` : "N/A";
|
|
@@ -4057,7 +3988,7 @@ ${achievementList.join("\n")}`;
|
|
|
4057
3988
|
});
|
|
4058
3989
|
ctx.command("ggcevo/切换pk", "切换玩家对战状态").alias("切换pk状态").action(async ({ session }) => {
|
|
4059
3990
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4060
|
-
if (!profile) return "🔒
|
|
3991
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4061
3992
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4062
3993
|
const [pkRecord] = await ctx.database.get("ggcevo_pk", { handle }) || [null];
|
|
4063
3994
|
const currentState = pkRecord?.enable ?? true;
|
|
@@ -4077,12 +4008,12 @@ ${achievementList.join("\n")}`;
|
|
|
4077
4008
|
const now = convertUTCtoChinaTime(/* @__PURE__ */ new Date());
|
|
4078
4009
|
const lastToggleTime = convertUTCtoChinaTime(lastToggle);
|
|
4079
4010
|
const diffDays = Math.floor((now.getTime() - lastToggleTime.getTime()) / (1e3 * 3600 * 24));
|
|
4011
|
+
const [careers] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4012
|
+
if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗阵营,无法切换PK状态!";
|
|
4080
4013
|
if (diffDays < 3 && lastToggleTime.getTime() !== 0) {
|
|
4081
4014
|
const remaining = 3 - diffDays;
|
|
4082
4015
|
return `状态切换冷却中,${remaining}天后再试(下次可切换时间:${new Date(lastToggle.getTime() + 3 * 864e5).toLocaleDateString("zh-CN")})。`;
|
|
4083
4016
|
}
|
|
4084
|
-
const [careers] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4085
|
-
if (careers?.group === "辛迪加海盗") return "您已经加入了辛迪加海盗阵营,无法切换PK状态!";
|
|
4086
4017
|
const action = currentState ? "关闭" : "开启";
|
|
4087
4018
|
await session.send(`您当前的PK状态为【${currentState ? "开启" : "关闭"}】,确认要${action}吗?(请在30秒内回复“是”确认)`);
|
|
4088
4019
|
const confirm = await session.prompt(3e4);
|
|
@@ -4115,7 +4046,24 @@ ${achievementList.join("\n")}`;
|
|
|
4115
4046
|
const CAREER_DISCOUNTS = [0, 0, 10, 15, 20];
|
|
4116
4047
|
const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
|
|
4117
4048
|
const careerDiscount = isCareerMatch ? CAREER_DISCOUNTS[techLevel - 1] : 0;
|
|
4118
|
-
const
|
|
4049
|
+
const techDiscount = Math.max(baseDiscount, careerDiscount);
|
|
4050
|
+
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
4051
|
+
handle,
|
|
4052
|
+
wishname: "蚱蜢优购",
|
|
4053
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
4054
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
4055
|
+
isused: false
|
|
4056
|
+
}).then((records) => records[0]);
|
|
4057
|
+
const grasshopperDiscount = activeWish ? 20 : 0;
|
|
4058
|
+
let totalDiscount = techDiscount + grasshopperDiscount;
|
|
4059
|
+
totalDiscount = Math.min(totalDiscount, 100);
|
|
4060
|
+
const discountDetails = [];
|
|
4061
|
+
if (techDiscount > 0) {
|
|
4062
|
+
discountDetails.push(`武器系统 Lv${techLevel}:${techDiscount}%`);
|
|
4063
|
+
}
|
|
4064
|
+
if (grasshopperDiscount > 0) {
|
|
4065
|
+
discountDetails.push(`蚱蜢优购祈愿:${grasshopperDiscount}%`);
|
|
4066
|
+
}
|
|
4119
4067
|
const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
|
|
4120
4068
|
stats[weapon.type] = (stats[weapon.type] || 0) + 1;
|
|
4121
4069
|
return stats;
|
|
@@ -4127,8 +4075,9 @@ ${achievementList.join("\n")}`;
|
|
|
4127
4075
|
"====================",
|
|
4128
4076
|
...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
|
|
4129
4077
|
"====================",
|
|
4130
|
-
|
|
4131
|
-
🔧
|
|
4078
|
+
totalDiscount > 0 && `
|
|
4079
|
+
🔧 当前购买折扣:
|
|
4080
|
+
${discountDetails.length ? ` ${discountDetails.join(" \n ")}` : ""}`
|
|
4132
4081
|
].filter(Boolean).join("\n");
|
|
4133
4082
|
}
|
|
4134
4083
|
if (!Object.keys(typeStats).includes(type)) {
|
|
@@ -4136,22 +4085,27 @@ ${achievementList.join("\n")}`;
|
|
|
4136
4085
|
${Object.keys(typeStats).join("、")}`;
|
|
4137
4086
|
}
|
|
4138
4087
|
const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
|
|
4139
|
-
const actualPrice = Math.floor(config2.price * (
|
|
4088
|
+
const actualPrice = Math.floor(config2.price * (100 - totalDiscount) / 100);
|
|
4140
4089
|
const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
|
|
4090
|
+
const specialEffect = config2.specialeffect ? `
|
|
4091
|
+
特殊效果:${config2.specialeffect}` : "";
|
|
4141
4092
|
return [
|
|
4142
4093
|
`【${name2}】`,
|
|
4143
4094
|
`类型:${config2.type}`,
|
|
4144
4095
|
`基础伤害:${config2.damage}`,
|
|
4145
|
-
`价格:${actualPrice}金币${
|
|
4096
|
+
`价格:${actualPrice}金币${totalDiscount > 0 ? ` (原价${config2.price})` : ""}`,
|
|
4146
4097
|
"特性:",
|
|
4147
4098
|
tagEffectsDesc,
|
|
4099
|
+
specialEffect,
|
|
4100
|
+
// 新增特殊效果显示
|
|
4148
4101
|
`描述:${config2.description}`
|
|
4149
|
-
].join("\n");
|
|
4102
|
+
].filter(Boolean).join("\n");
|
|
4150
4103
|
});
|
|
4151
4104
|
return [
|
|
4152
4105
|
`🏪 咕咕武器库 - ${type} 🏪`,
|
|
4153
4106
|
"使用“购买 武器名称”指令进行购买",
|
|
4154
|
-
|
|
4107
|
+
totalDiscount > 0 && `🔧 当前购买折扣:
|
|
4108
|
+
${discountDetails.length ? ` ${discountDetails.join(" \n ")}` : ""}`,
|
|
4155
4109
|
"====================",
|
|
4156
4110
|
...items,
|
|
4157
4111
|
items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
|
|
@@ -4199,10 +4153,10 @@ ${validTypes.join("、")}`;
|
|
|
4199
4153
|
});
|
|
4200
4154
|
ctx.command("ggcevo/购买 <item>").action(async ({ session }, item) => {
|
|
4201
4155
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4202
|
-
if (!profile) return "🔒
|
|
4156
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4203
4157
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4204
4158
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4205
|
-
if (existingEntries.length > 0) return "
|
|
4159
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
4206
4160
|
const allItems = { ...weaponConfig, ...SyndicatedItems };
|
|
4207
4161
|
if (!item) return "请输入“购买 物品名称”来购买所需物品。";
|
|
4208
4162
|
const config2 = allItems[item];
|
|
@@ -4219,8 +4173,8 @@ ${validTypes.join("、")}`;
|
|
|
4219
4173
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
4220
4174
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4221
4175
|
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 });
|
|
4222
|
-
let discountDetails = [];
|
|
4223
4176
|
let totalDiscount = 0;
|
|
4177
|
+
let discountDetails = [];
|
|
4224
4178
|
if (isWeapon && careerData?.group === "人类联盟") {
|
|
4225
4179
|
const techDiscountTable = {
|
|
4226
4180
|
3: [0, 10],
|
|
@@ -4235,7 +4189,7 @@ ${validTypes.join("、")}`;
|
|
|
4235
4189
|
if (techDiscount > 0) {
|
|
4236
4190
|
totalDiscount += techDiscount;
|
|
4237
4191
|
discountDetails.push(
|
|
4238
|
-
`武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""}
|
|
4192
|
+
`武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""}:${techDiscount}%折扣`
|
|
4239
4193
|
);
|
|
4240
4194
|
}
|
|
4241
4195
|
}
|
|
@@ -4249,8 +4203,9 @@ ${validTypes.join("、")}`;
|
|
|
4249
4203
|
}).then((records) => records[0]) : null;
|
|
4250
4204
|
if (activeWish) {
|
|
4251
4205
|
const wishDiscount = 20;
|
|
4252
|
-
totalDiscount
|
|
4253
|
-
discountDetails.push(
|
|
4206
|
+
totalDiscount += wishDiscount;
|
|
4207
|
+
discountDetails.push(`蚱蜢优购祈愿生效:${wishDiscount}%折扣`);
|
|
4208
|
+
totalDiscount = Math.min(totalDiscount, 100);
|
|
4254
4209
|
}
|
|
4255
4210
|
let actualPrice = config2.price;
|
|
4256
4211
|
if (totalDiscount > 0) {
|
|
@@ -4260,7 +4215,7 @@ ${validTypes.join("、")}`;
|
|
|
4260
4215
|
if ((signInfo?.totalRewards || 0) < actualPrice) {
|
|
4261
4216
|
let priceInfo = `需要 ${actualPrice} 金币`;
|
|
4262
4217
|
if (discountDetails.length > 0) {
|
|
4263
|
-
priceInfo +=
|
|
4218
|
+
priceInfo += `(原价 ${config2.price})`;
|
|
4264
4219
|
}
|
|
4265
4220
|
return `❌ 金币不足,${priceInfo}`;
|
|
4266
4221
|
}
|
|
@@ -4325,7 +4280,7 @@ ${validTypes.join("、")}`;
|
|
|
4325
4280
|
});
|
|
4326
4281
|
ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
|
|
4327
4282
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4328
|
-
if (!profile) return "🔒
|
|
4283
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4329
4284
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4330
4285
|
const weapons = await ctx.database.get("ggcevo_equipment", {
|
|
4331
4286
|
handle
|
|
@@ -4345,7 +4300,7 @@ ${validTypes.join("、")}`;
|
|
|
4345
4300
|
].join("\n");
|
|
4346
4301
|
}));
|
|
4347
4302
|
return [
|
|
4348
|
-
`🛡️ ${handle}
|
|
4303
|
+
`🛡️ ${handle}拥有的武器`,
|
|
4349
4304
|
'使用"装备 武器名称"来装备武器',
|
|
4350
4305
|
"⚡表示当前装备武器",
|
|
4351
4306
|
"──────────────",
|
|
@@ -4357,20 +4312,20 @@ ${validTypes.join("、")}`;
|
|
|
4357
4312
|
});
|
|
4358
4313
|
ctx.command("ggcevo/装备 <weapon>").action(async ({ session }, weapon) => {
|
|
4359
4314
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4360
|
-
if (!profile) return "🔒
|
|
4361
|
-
if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4362
|
-
if (!weaponConfig[weapon]) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4363
|
-
const config2 = weaponConfig[weapon];
|
|
4315
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4364
4316
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4365
4317
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4366
4318
|
if (existingEntries.length > 0) {
|
|
4367
|
-
return
|
|
4319
|
+
return `⛔ 您已被列入黑名单`;
|
|
4368
4320
|
}
|
|
4321
|
+
if (!weapon) return "请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4322
|
+
if (!weaponConfig[weapon]) return "武器名称错误,请输入“装备 武器名称”来装备一把你拥有的武器。";
|
|
4323
|
+
const config2 = weaponConfig[weapon];
|
|
4369
4324
|
const [owned] = await ctx.database.get("ggcevo_equipment", {
|
|
4370
4325
|
handle,
|
|
4371
4326
|
weaponId: config2.id
|
|
4372
4327
|
});
|
|
4373
|
-
if (!owned) return "
|
|
4328
|
+
if (!owned) return "您尚未获得该武器。";
|
|
4374
4329
|
await ctx.database.withTransaction(async () => {
|
|
4375
4330
|
await ctx.database.set(
|
|
4376
4331
|
"ggcevo_equipment",
|
|
@@ -4391,10 +4346,10 @@ ${validTypes.join("、")}`;
|
|
|
4391
4346
|
});
|
|
4392
4347
|
ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
|
|
4393
4348
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4394
|
-
if (!profile) return "🔒
|
|
4349
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4395
4350
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4396
4351
|
if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
|
|
4397
|
-
return "
|
|
4352
|
+
return "⛔ 您已被列入黑名单";
|
|
4398
4353
|
}
|
|
4399
4354
|
if (!target) {
|
|
4400
4355
|
return generateUpgradePriceList(handle);
|
|
@@ -4412,10 +4367,10 @@ ${validTypes.join("、")}`;
|
|
|
4412
4367
|
});
|
|
4413
4368
|
ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
|
|
4414
4369
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4415
|
-
if (!profile) return "🔒
|
|
4370
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4416
4371
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4417
4372
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4418
|
-
if (existingEntries.length > 0) return "
|
|
4373
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
4419
4374
|
const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
|
|
4420
4375
|
const processModInstallation = /* @__PURE__ */ __name(async () => {
|
|
4421
4376
|
const modInfo = modConfig[mod];
|
|
@@ -4424,7 +4379,7 @@ ${validTypes.join("、")}`;
|
|
|
4424
4379
|
handle,
|
|
4425
4380
|
weaponId: weaponConfig[weapon].id
|
|
4426
4381
|
});
|
|
4427
|
-
if (!equipment) return "
|
|
4382
|
+
if (!equipment) return "您尚未获得该武器。";
|
|
4428
4383
|
if (modInfo.isExclusive) {
|
|
4429
4384
|
if (modInfo.exclusiveTo !== weapon) return `❌ 该模块只能安装在${modInfo.exclusiveTo}上。`;
|
|
4430
4385
|
const hasExclusive = equipment.installedMods.some((m) => modConfig[m]?.isExclusive);
|
|
@@ -4467,7 +4422,7 @@ ${validTypes.join("、")}`;
|
|
|
4467
4422
|
return [
|
|
4468
4423
|
`✅ ${weapon} 成功安装 ${mod}!`,
|
|
4469
4424
|
discountMsg,
|
|
4470
|
-
`花费金币:${actualCost}`,
|
|
4425
|
+
`花费金币:${actualCost}${discountRate > 0 ? `(原价${modInfo.cost})` : ""}`,
|
|
4471
4426
|
`改装槽:${equipment.installedMods.length + 1}/${equipment.modificationSlots}`
|
|
4472
4427
|
].join("\n");
|
|
4473
4428
|
}, "processModInstallation");
|
|
@@ -4510,7 +4465,8 @@ ${validTypes.join("、")}`;
|
|
|
4510
4465
|
const universalMods = Object.entries(modConfig).filter(([_, m]) => !m.isExclusive).map(([name2, cfg]) => formatMod(name2, cfg));
|
|
4511
4466
|
return [
|
|
4512
4467
|
"🛠️ 通用武器模块 🛠️",
|
|
4513
|
-
"使用「改装 武器名称
|
|
4468
|
+
"使用「改装 武器名称 模块名称」安装通用模块",
|
|
4469
|
+
"输入「改装 武器名称」查询武器的专属模块",
|
|
4514
4470
|
universalDiscountRate > 0 && `🔧 当前通用模块折扣:${universalDiscountRate}% (武器升级平台 Lv${techLevel})`,
|
|
4515
4471
|
"====================",
|
|
4516
4472
|
universalMods.join("\n\n")
|
|
@@ -4527,10 +4483,10 @@ ${validTypes.join("、")}`;
|
|
|
4527
4483
|
const session = argv.session;
|
|
4528
4484
|
let broadcastMessage = null;
|
|
4529
4485
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4530
|
-
if (!profile) return "🔒
|
|
4486
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4531
4487
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4532
4488
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4533
|
-
if (existingEntries.length > 0) return "
|
|
4489
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
4534
4490
|
const getActiveBossNames = /* @__PURE__ */ __name(async () => {
|
|
4535
4491
|
const activeBosses2 = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4536
4492
|
return activeBosses2.map((b) => b.name).join(",");
|
|
@@ -4569,7 +4525,7 @@ ${validTypes.join("、")}`;
|
|
|
4569
4525
|
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
4570
4526
|
const [weaponName, weaponData] = weaponConfigEntry;
|
|
4571
4527
|
if (!weaponData.isantiair && targetBoss.groupId === 5) {
|
|
4572
|
-
return "
|
|
4528
|
+
return "您当前装备的武器无法攻击空中目标!";
|
|
4573
4529
|
}
|
|
4574
4530
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4575
4531
|
if (!activeBosses.length) return "当前没有存活的异形,请等待下一轮刷新。";
|
|
@@ -4579,6 +4535,120 @@ ${validTypes.join("、")}`;
|
|
|
4579
4535
|
if (!bossGroup) return "无法获取异形组配置。";
|
|
4580
4536
|
const maxHP = targetBoss.type === "主宰" ? bossGroup.main.maxHP : bossGroup.minions.find((m) => m.name === targetBoss.name)?.maxHP || 0;
|
|
4581
4537
|
const { damage, hasCrit, effectMessage } = await calculateTotalDamage(ctx, session, equippedWeapon, targetBoss);
|
|
4538
|
+
const extraDamages = [];
|
|
4539
|
+
const actuallyDead = [];
|
|
4540
|
+
let scatterBroadcast = null;
|
|
4541
|
+
if (equippedWeapon.installedMods?.includes("光束曲射晶片") && weaponName === "碎骨步枪") {
|
|
4542
|
+
const activeBosses2 = await ctx.database.get("ggcevo_boss", {
|
|
4543
|
+
isActive: true,
|
|
4544
|
+
name: { $ne: targetBoss.name }
|
|
4545
|
+
// 排除当前目标
|
|
4546
|
+
});
|
|
4547
|
+
if (activeBosses2.length > 0) {
|
|
4548
|
+
effectMessage.push("🔆 【光束曲射晶片】触发!");
|
|
4549
|
+
const baseDamage = weaponData.damage * (1 + 0.1 * equippedWeapon.level);
|
|
4550
|
+
const secondaryDamage = Math.round(baseDamage * 0.5);
|
|
4551
|
+
for (const secondaryTarget of activeBosses2) {
|
|
4552
|
+
const secondaryMaxHP = getBossMaxHP(secondaryTarget.name);
|
|
4553
|
+
let currentDamage = secondaryDamage;
|
|
4554
|
+
const passiveResult2 = await PassiveHandler.handlePassives(
|
|
4555
|
+
ctx,
|
|
4556
|
+
secondaryTarget,
|
|
4557
|
+
currentDamage,
|
|
4558
|
+
secondaryTarget.HP - currentDamage,
|
|
4559
|
+
secondaryMaxHP,
|
|
4560
|
+
weaponName,
|
|
4561
|
+
weaponData,
|
|
4562
|
+
activeBosses2,
|
|
4563
|
+
bossGroup
|
|
4564
|
+
);
|
|
4565
|
+
const finalDamage = passiveResult2.initialDamage;
|
|
4566
|
+
const actualDamage = Math.min(finalDamage, secondaryTarget.HP);
|
|
4567
|
+
extraDamages.push({
|
|
4568
|
+
name: secondaryTarget.name,
|
|
4569
|
+
damage: actualDamage
|
|
4570
|
+
});
|
|
4571
|
+
const newHP = passiveResult2.currentHP;
|
|
4572
|
+
if (passiveResult2.skillUpdates.length > 0) {
|
|
4573
|
+
await PassiveHandler.applySkillUpdates(ctx, passiveResult2.skillUpdates);
|
|
4574
|
+
}
|
|
4575
|
+
const isDead = newHP <= 0;
|
|
4576
|
+
await ctx.database.set(
|
|
4577
|
+
"ggcevo_boss",
|
|
4578
|
+
{ name: secondaryTarget.name },
|
|
4579
|
+
{
|
|
4580
|
+
HP: Math.max(newHP, 0),
|
|
4581
|
+
isActive: !isDead
|
|
4582
|
+
}
|
|
4583
|
+
);
|
|
4584
|
+
effectMessage.push(...passiveResult2.messages.map((m) => `+ 对 ${secondaryTarget.name} ${m}`));
|
|
4585
|
+
if (isDead) {
|
|
4586
|
+
actuallyDead.push(secondaryTarget.name);
|
|
4587
|
+
if (secondaryTarget.type === "子代") {
|
|
4588
|
+
if (secondaryTarget.name === "机械感染虫") {
|
|
4589
|
+
const [mainBoss] = await ctx.database.get("ggcevo_boss", {
|
|
4590
|
+
groupId: secondaryTarget.groupId,
|
|
4591
|
+
type: "主宰",
|
|
4592
|
+
isActive: true
|
|
4593
|
+
});
|
|
4594
|
+
if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
|
|
4595
|
+
await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
|
|
4596
|
+
skills: [...mainBoss.skills, "孤立无援"]
|
|
4597
|
+
});
|
|
4598
|
+
broadcastMessage = "💥 机械感染虫已阵亡,空间站感染虫进入【孤立无援】状态,受到的伤害+20%!";
|
|
4599
|
+
}
|
|
4600
|
+
} else {
|
|
4601
|
+
const remainingMinions = await ctx.database.get("ggcevo_boss", {
|
|
4602
|
+
groupId: secondaryTarget.groupId,
|
|
4603
|
+
type: "子代",
|
|
4604
|
+
isActive: true
|
|
4605
|
+
});
|
|
4606
|
+
if (remainingMinions.length === 0) {
|
|
4607
|
+
const [mainBoss] = await ctx.database.get("ggcevo_boss", {
|
|
4608
|
+
groupId: secondaryTarget.groupId,
|
|
4609
|
+
type: "主宰",
|
|
4610
|
+
isActive: true
|
|
4611
|
+
});
|
|
4612
|
+
if (mainBoss && !mainBoss.skills.includes("孤立无援")) {
|
|
4613
|
+
await ctx.database.set("ggcevo_boss", { name: mainBoss.name }, {
|
|
4614
|
+
skills: [...mainBoss.skills, "孤立无援"]
|
|
4615
|
+
});
|
|
4616
|
+
broadcastMessage = `💥 所有子代已阵亡,${mainBoss.name}进入【孤立无援】状态,受到的伤害+20%!`;
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
}
|
|
4620
|
+
} else if (secondaryTarget.type === "主宰") {
|
|
4621
|
+
await ctx.database.set(
|
|
4622
|
+
"ggcevo_boss",
|
|
4623
|
+
{ groupId: secondaryTarget.groupId },
|
|
4624
|
+
{
|
|
4625
|
+
isActive: false,
|
|
4626
|
+
HP: 0
|
|
4627
|
+
}
|
|
4628
|
+
);
|
|
4629
|
+
const respawnTime = /* @__PURE__ */ new Date();
|
|
4630
|
+
respawnTime.setSeconds(respawnTime.getSeconds() + 3600);
|
|
4631
|
+
await ctx.database.set(
|
|
4632
|
+
"ggcevo_boss",
|
|
4633
|
+
{ name: secondaryTarget.name },
|
|
4634
|
+
{ respawnTime }
|
|
4635
|
+
);
|
|
4636
|
+
const { rewardMessages } = await handleBossDefeatRewards(ctx, secondaryTarget);
|
|
4637
|
+
await ctx.database.remove("ggcevo_boss_damage", {
|
|
4638
|
+
bossGroupId: secondaryTarget.groupId
|
|
4639
|
+
});
|
|
4640
|
+
scatterBroadcast = [
|
|
4641
|
+
`🎯 主宰 ${secondaryTarget.name} 已被 ${session.username} 的散射伤害击败!`,
|
|
4642
|
+
`所有子代已消失,下一个主宰将在1小时后重生`,
|
|
4643
|
+
"",
|
|
4644
|
+
"🏆 伤害排行榜奖励:",
|
|
4645
|
+
...rewardMessages
|
|
4646
|
+
].join("\n");
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4582
4652
|
let initialDamage = Math.min(damage, targetBoss.HP);
|
|
4583
4653
|
let currentHP = targetBoss.HP - initialDamage;
|
|
4584
4654
|
let passiveMessages = [];
|
|
@@ -4604,11 +4674,12 @@ ${validTypes.join("、")}`;
|
|
|
4604
4674
|
handle,
|
|
4605
4675
|
bossGroupId: targetBoss.groupId
|
|
4606
4676
|
});
|
|
4677
|
+
const totalDamage = initialDamage + extraDamages.reduce((sum, d) => sum + d.damage, 0);
|
|
4607
4678
|
await ctx.database.upsert("ggcevo_boss_damage", [{
|
|
4608
4679
|
handle,
|
|
4609
4680
|
bossGroupId: targetBoss.groupId,
|
|
4610
4681
|
playerName: session.username,
|
|
4611
|
-
totalDamage: (existingRecord?.totalDamage || 0) +
|
|
4682
|
+
totalDamage: (existingRecord?.totalDamage || 0) + totalDamage,
|
|
4612
4683
|
// 改为实际伤害
|
|
4613
4684
|
attackCount: (existingRecord?.attackCount || 0) + 1,
|
|
4614
4685
|
lastattackDate: /* @__PURE__ */ new Date()
|
|
@@ -4630,7 +4701,7 @@ ${validTypes.join("、")}`;
|
|
|
4630
4701
|
{ name: targetBoss.name },
|
|
4631
4702
|
{ respawnTime }
|
|
4632
4703
|
);
|
|
4633
|
-
const { rewardMessages } = await handleBossDefeatRewards(ctx, targetBoss
|
|
4704
|
+
const { rewardMessages } = await handleBossDefeatRewards(ctx, targetBoss);
|
|
4634
4705
|
await ctx.database.remove("ggcevo_boss_damage", {
|
|
4635
4706
|
bossGroupId: targetBoss.groupId
|
|
4636
4707
|
});
|
|
@@ -4715,7 +4786,7 @@ ${validTypes.join("、")}`;
|
|
|
4715
4786
|
}], ["handle"]);
|
|
4716
4787
|
redcrystalMessage = "🔴 清洁工职业加成:获得1枚红晶";
|
|
4717
4788
|
}
|
|
4718
|
-
const finalReward = Math.round(
|
|
4789
|
+
const finalReward = Math.round(totalDamage * careerMultiplier);
|
|
4719
4790
|
const [existingSign] = await ctx.database.get("ggcevo_sign", { handle });
|
|
4720
4791
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
4721
4792
|
handle,
|
|
@@ -4734,16 +4805,25 @@ ${effectMessage.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4734
4805
|
${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
4735
4806
|
] : [],
|
|
4736
4807
|
`造成伤害:${initialDamage}${hasCrit ? "(✨ 暴击)" : ""}`,
|
|
4808
|
+
...extraDamages.length > 0 ? [
|
|
4809
|
+
`⚡ 散射伤害:`,
|
|
4810
|
+
...extraDamages.map((d) => `▸ 对 ${d.name} 造成 ${d.damage} 伤害`)
|
|
4811
|
+
] : [],
|
|
4737
4812
|
`获得金币:${finalReward}${careerMessage}`,
|
|
4738
4813
|
redcrystalMessage,
|
|
4739
4814
|
`目标剩余HP:${Math.max(currentHP, 0)}/${maxHP}`,
|
|
4815
|
+
...actuallyDead.length > 0 ? [
|
|
4816
|
+
`💀 散射击杀:${actuallyDead.join(", ")}`
|
|
4817
|
+
] : [],
|
|
4740
4818
|
isDefeated ? `🎉 恭喜,已成功击败 ${targetBoss.name}!` : ""
|
|
4741
4819
|
].filter((line) => line).join("\n");
|
|
4742
4820
|
await session.send(resultMessage);
|
|
4743
|
-
if (
|
|
4744
|
-
const
|
|
4821
|
+
if (scatterBroadcast) {
|
|
4822
|
+
const groupId = [...config2.groupId];
|
|
4823
|
+
await ctx.broadcast(groupId, Array.isArray(scatterBroadcast) ? scatterBroadcast.join("\n") : scatterBroadcast);
|
|
4824
|
+
} else if (broadcastMessage) {
|
|
4745
4825
|
const groupId = [...config2.groupId];
|
|
4746
|
-
await ctx.broadcast(groupId,
|
|
4826
|
+
await ctx.broadcast(groupId, Array.isArray(broadcastMessage) ? broadcastMessage.join("\n") : broadcastMessage);
|
|
4747
4827
|
}
|
|
4748
4828
|
});
|
|
4749
4829
|
ctx.command("ggcevo/攻击假人").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").action(async (argv) => {
|
|
@@ -4752,10 +4832,10 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4752
4832
|
const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
|
|
4753
4833
|
const tags = parseList(options.tags);
|
|
4754
4834
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4755
|
-
if (!profile) return "🔒
|
|
4835
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4756
4836
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4757
4837
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4758
|
-
if (existingEntries.length > 0) return "
|
|
4838
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
4759
4839
|
const [equippedWeapon] = await ctx.database.get("ggcevo_equipment", {
|
|
4760
4840
|
handle,
|
|
4761
4841
|
equipped: true
|
|
@@ -4792,14 +4872,14 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4792
4872
|
// 这里添加符号
|
|
4793
4873
|
] : [],
|
|
4794
4874
|
`📊 理论伤害值:${damage}${hasCrit ? " (✨ 触发暴击)" : ""}`,
|
|
4795
|
-
"💡 提示:使用 -t 重甲,生物…… 添加测试标签"
|
|
4875
|
+
"💡 提示:使用 -t 重甲,生物……(标签之间用英文逗号分隔) 添加测试标签"
|
|
4796
4876
|
].filter((line) => line).join("\n");
|
|
4797
4877
|
});
|
|
4798
4878
|
ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
4799
4879
|
const pageNum = parseInt(page) || 1;
|
|
4800
4880
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
4801
4881
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4802
|
-
if (!activeBosses.length) return "
|
|
4882
|
+
if (!activeBosses.length) return "当前没有存活的异形,请等待下次刷新。";
|
|
4803
4883
|
const mainBoss = activeBosses.find((b) => b.type === "主宰");
|
|
4804
4884
|
if (!mainBoss) return "当前数据异常,请联系管理员";
|
|
4805
4885
|
const offset = (pageNum - 1) * 10;
|
|
@@ -4810,7 +4890,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4810
4890
|
ctx.database.select("ggcevo_boss_damage").where({ bossGroupId: mainBoss.groupId }).execute((row) => import_koishi.$.count(row.handle))
|
|
4811
4891
|
]);
|
|
4812
4892
|
const totalPages = Math.ceil(total / 10);
|
|
4813
|
-
if (pageNum > totalPages) return
|
|
4893
|
+
if (pageNum > totalPages) return `查询失败,最多有 ${totalPages} 页`;
|
|
4814
4894
|
if (!records.length) return "暂无伤害记录";
|
|
4815
4895
|
const rankingText = records.map(
|
|
4816
4896
|
(record, index) => `${offset + index + 1}. ${record.playerName || "未知玩家"} | 总伤害: ${record.totalDamage} | 攻击次数: ${record.attackCount}`
|
|
@@ -4826,7 +4906,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4826
4906
|
});
|
|
4827
4907
|
ctx.command("ggcevo/异形信息", "查看当前主宰信息").alias("yx信息").action(async () => {
|
|
4828
4908
|
const activeBosses = await ctx.database.get("ggcevo_boss", { isActive: true });
|
|
4829
|
-
if (!activeBosses.length) return "
|
|
4909
|
+
if (!activeBosses.length) return "当前没有存活的异形,请等待下次刷新。";
|
|
4830
4910
|
const mainBoss = activeBosses.find((b) => b.type === "主宰");
|
|
4831
4911
|
const minions = activeBosses.filter((b) => b.type === "子代");
|
|
4832
4912
|
if (!mainBoss) return "当前数据异常,请联系管理员";
|
|
@@ -4858,7 +4938,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4858
4938
|
}
|
|
4859
4939
|
return result.join("\n");
|
|
4860
4940
|
});
|
|
4861
|
-
ctx.command("ggcevo/初始化异形 <groupid:number>", "初始化指定主宰组", { authority: 3 }).action(async (_, groupid) => {
|
|
4941
|
+
ctx.command("ggcevo/初始化异形 <groupid:number>", "初始化指定主宰组", { authority: 3 }).alias("初始化yx").action(async (_, groupid) => {
|
|
4862
4942
|
if (!groupid) groupid = 1;
|
|
4863
4943
|
const bossConfig = bossPool.find((g) => g.main.id === groupid);
|
|
4864
4944
|
if (!bossConfig) {
|
|
@@ -4892,11 +4972,11 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4892
4972
|
ctx.command("ggcevo/祈愿").action(async (argv) => {
|
|
4893
4973
|
const session = argv.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 });
|
|
4899
|
-
if (existingEntries.length > 0) return "
|
|
4979
|
+
if (existingEntries.length > 0) return "⛔ 您已被列入黑名单";
|
|
4900
4980
|
const [sign] = await ctx.database.get("ggcevo_sign", { handle });
|
|
4901
4981
|
if (!sign || sign.totalRewards < 50) return "需要50金币进行祈愿,您的金币不足。";
|
|
4902
4982
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -4967,19 +5047,19 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
4967
5047
|
return `✨ 祈愿成功!花费50枚金币获得【${effect.name}】效果:${effect.effect}
|
|
4968
5048
|
⏳ 效果持续至 ${formattedEndTime}`;
|
|
4969
5049
|
});
|
|
4970
|
-
ctx.command("
|
|
5050
|
+
ctx.command("ggcevo/兑换金币", "使用兑换券兑换金币").action(async ({ session }) => {
|
|
4971
5051
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4972
|
-
if (!profile) return "🔒
|
|
5052
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
4973
5053
|
const { regionId, realmId, profileId } = profile;
|
|
4974
5054
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
4975
5055
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4976
5056
|
if (existingEntries.length > 0) {
|
|
4977
|
-
return
|
|
5057
|
+
return `⛔ 您已被列入黑名单`;
|
|
4978
5058
|
}
|
|
4979
5059
|
await session.send(`请输入你要使用多少张兑换券来兑换金币?(请在30秒内回复数字,回复“0”为取消兑换)
|
|
4980
5060
|
注意:1张兑换券=2000金币`);
|
|
4981
5061
|
const exchangeInput = await session.prompt(3e4);
|
|
4982
|
-
if (!exchangeInput) return "
|
|
5062
|
+
if (!exchangeInput) return "已取消操作,请重新输入。";
|
|
4983
5063
|
const exchangeCount = parseInt(exchangeInput, 10);
|
|
4984
5064
|
if (isNaN(exchangeCount)) return "请输入有效的数字!";
|
|
4985
5065
|
if (exchangeCount < 0) return "兑换数量不能为负数!";
|
|
@@ -5006,13 +5086,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5006
5086
|
});
|
|
5007
5087
|
return `成功使用${exchangeCount}张兑换券,获得${goldAmount}枚金币!`;
|
|
5008
5088
|
});
|
|
5009
|
-
ctx.command("
|
|
5089
|
+
ctx.command("ggcevo/兑换红晶", "使用金币兑换红晶").action(async ({ session }) => {
|
|
5010
5090
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5011
|
-
if (!profile) return "🔒
|
|
5091
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5012
5092
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5013
5093
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
5014
5094
|
if (existingEntries.length > 0) {
|
|
5015
|
-
return
|
|
5095
|
+
return `⛔ 您已被列入黑名单`;
|
|
5016
5096
|
}
|
|
5017
5097
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5018
5098
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
@@ -5021,7 +5101,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5021
5101
|
await session.send(`请输入你想要兑换多少红晶?(请在30秒内回复数字,回复“0”为取消兑换)
|
|
5022
5102
|
注意:每块红晶需要950金币。`);
|
|
5023
5103
|
const exchangeInput = await session.prompt(3e4);
|
|
5024
|
-
if (!exchangeInput) return "
|
|
5104
|
+
if (!exchangeInput) return "已取消操作,请重新输入。";
|
|
5025
5105
|
const exchangeCount = parseInt(exchangeInput, 10);
|
|
5026
5106
|
if (isNaN(exchangeCount)) return "请输入有效的数字!";
|
|
5027
5107
|
if (exchangeCount < 0) return "兑换数量不能为负数!";
|
|
@@ -5048,12 +5128,12 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5048
5128
|
});
|
|
5049
5129
|
ctx.command("ggcevo/加入 <faction>", "加入阵营").alias("加入阵营").action(async ({ session }, faction) => {
|
|
5050
5130
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5051
|
-
if (!profile) return "🔒
|
|
5131
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5052
5132
|
const { regionId, realmId, profileId } = profile;
|
|
5053
5133
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
5054
5134
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
5055
5135
|
if (existingEntries.length > 0) {
|
|
5056
|
-
return
|
|
5136
|
+
return `⛔ 您已被列入黑名单`;
|
|
5057
5137
|
}
|
|
5058
5138
|
const validFactions = ["人类联盟", "辛迪加海盗"];
|
|
5059
5139
|
if (!faction) return `请输入“加入 阵营名称”加入对应阵营
|
|
@@ -5089,7 +5169,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5089
5169
|
} else if (faction === "辛迪加海盗") {
|
|
5090
5170
|
const [pkData] = await ctx.database.get("ggcevo_pk", { handle });
|
|
5091
5171
|
if (userCoins < 2e3) {
|
|
5092
|
-
return
|
|
5172
|
+
return `加入辛迪加海盗需要缴纳2000金币并且永久开启PK功能,你当前拥有${userCoins}金币`;
|
|
5093
5173
|
}
|
|
5094
5174
|
if (pkData && !pkData?.enable) {
|
|
5095
5175
|
return "当前PK功能未开启,无法加入辛迪加海盗。";
|
|
@@ -5117,11 +5197,11 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5117
5197
|
});
|
|
5118
5198
|
ctx.command("ggcevo/转职 [profession]", "转职系统").action(async ({ session }, profession) => {
|
|
5119
5199
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5120
|
-
if (!profile) return "🔒
|
|
5200
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5121
5201
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5122
5202
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
5123
5203
|
if (existingEntries.length > 0) {
|
|
5124
|
-
return
|
|
5204
|
+
return `⛔ 您已被列入黑名单`;
|
|
5125
5205
|
}
|
|
5126
5206
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5127
5207
|
if (!careerData) return "请先加入阵营后使用转职功能。";
|
|
@@ -5169,7 +5249,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5169
5249
|
try {
|
|
5170
5250
|
if (careerData.group === "人类联盟") {
|
|
5171
5251
|
if (userCoins < targetProfession.costcoins) {
|
|
5172
|
-
return `转职需要 ${targetProfession.costcoins}
|
|
5252
|
+
return `转职需要 ${targetProfession.costcoins} 金币,您当前拥有 ${userCoins}`;
|
|
5173
5253
|
}
|
|
5174
5254
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
5175
5255
|
handle,
|
|
@@ -5177,7 +5257,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5177
5257
|
}], ["handle"]);
|
|
5178
5258
|
} else if (careerData.group === "辛迪加海盗") {
|
|
5179
5259
|
if (userRedCrystal < (targetProfession.costredcrystal || 0)) {
|
|
5180
|
-
return `需要红晶 ${targetProfession.costredcrystal}
|
|
5260
|
+
return `需要红晶 ${targetProfession.costredcrystal},您当前拥有 ${userRedCrystal}`;
|
|
5181
5261
|
}
|
|
5182
5262
|
await Promise.all([
|
|
5183
5263
|
ctx.database.upsert("ggcevo_careers", [{
|
|
@@ -5202,7 +5282,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5202
5282
|
const [profile] = await ctx.database.get("sc2arcade_player", {
|
|
5203
5283
|
userId: session.userId
|
|
5204
5284
|
});
|
|
5205
|
-
if (!profile) return "🔒
|
|
5285
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5206
5286
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5207
5287
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5208
5288
|
if (!careerData) return "您尚未加入任何阵营。";
|
|
@@ -5241,7 +5321,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5241
5321
|
});
|
|
5242
5322
|
ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
|
|
5243
5323
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5244
|
-
if (!profile) return "🔒
|
|
5324
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5245
5325
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5246
5326
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5247
5327
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
@@ -5303,23 +5383,23 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5303
5383
|
];
|
|
5304
5384
|
return [
|
|
5305
5385
|
`🏴☠️ 辛迪加黑市 - ${normalizedType} 🏴☠️`,
|
|
5306
|
-
"使用“订购
|
|
5386
|
+
"使用“订购 物品名称”进行购买(仅消耗红晶)",
|
|
5307
5387
|
"====================",
|
|
5308
5388
|
...items
|
|
5309
5389
|
].join("\n\n");
|
|
5310
5390
|
});
|
|
5311
5391
|
ctx.command("ggcevo/订购 <item>").action(async ({ session }, item) => {
|
|
5312
5392
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5313
|
-
if (!profile) return "🔒
|
|
5393
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5314
5394
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5315
5395
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5316
|
-
return "
|
|
5396
|
+
return "⛔ 您已被列入黑名单";
|
|
5317
5397
|
}
|
|
5318
5398
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5319
5399
|
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
5320
5400
|
return "🚫 该功能需要【辛迪加海盗】阵营权限";
|
|
5321
5401
|
}
|
|
5322
|
-
if (!item) return "请输入“订购
|
|
5402
|
+
if (!item) return "请输入“订购 物品名称”向辛迪加总部订购物品。";
|
|
5323
5403
|
const isWeapon = Object.prototype.hasOwnProperty.call(weaponConfig, item);
|
|
5324
5404
|
const isSyndicatedItem = Object.prototype.hasOwnProperty.call(SyndicatedItems, item);
|
|
5325
5405
|
if (!isWeapon && !isSyndicatedItem) return "❌ 无效物品名称";
|
|
@@ -5396,7 +5476,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5396
5476
|
ctx.command("ggcevo/仓库").action(async (argv) => {
|
|
5397
5477
|
const session = argv.session;
|
|
5398
5478
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5399
|
-
if (!profile) return "🔒
|
|
5479
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5400
5480
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5401
5481
|
const [items, signData, careerData] = await Promise.all([
|
|
5402
5482
|
ctx.database.get("ggcevo_warehouse", { handle }),
|
|
@@ -5427,7 +5507,7 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5427
5507
|
// 移除数量显示在标题
|
|
5428
5508
|
`类型:${itemData.type} | 持有数量:${warehouseItem.quantity}`,
|
|
5429
5509
|
// 从warehouse表读取实际数量
|
|
5430
|
-
|
|
5510
|
+
`效果:${itemData.effects}`,
|
|
5431
5511
|
`描述:${itemData.description}`,
|
|
5432
5512
|
"――――――――――――――"
|
|
5433
5513
|
].join("\n");
|
|
@@ -5439,12 +5519,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5439
5519
|
ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
|
|
5440
5520
|
const session = argv.session;
|
|
5441
5521
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5442
|
-
if (!profile) return "🔒
|
|
5522
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5443
5523
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5444
5524
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5445
5525
|
return "⛔ 您已被列入黑名单";
|
|
5446
5526
|
}
|
|
5447
5527
|
try {
|
|
5528
|
+
if (!itemName) return "请输入“使用 物品名称 (可选目标)”使用仓库中的物品。";
|
|
5448
5529
|
const warehouseItems = await ctx.database.get("ggcevo_warehouse", { handle });
|
|
5449
5530
|
const targetItem = warehouseItems.find((item) => {
|
|
5450
5531
|
const entry = Object.entries(SyndicatedItems).find(
|
|
@@ -5479,13 +5560,14 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5479
5560
|
});
|
|
5480
5561
|
ctx.command("ggcevo/科技 [techName]", "查看空间站科技信息").usage("输入“科技”查看列表,或“科技 科技名称”查看详细信息").action(async ({ session }, techName) => {
|
|
5481
5562
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5482
|
-
if (!profile) return "🔒
|
|
5563
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5483
5564
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5484
5565
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5485
5566
|
if (!careerData || careerData.group !== "人类联盟") {
|
|
5486
5567
|
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
5487
5568
|
}
|
|
5488
5569
|
const romanNumerals = { 1: "I", 2: "II", 3: "III", 4: "IV", 5: "V" };
|
|
5570
|
+
const isIntelligenceOfficer = careerData?.career === "情报副官";
|
|
5489
5571
|
if (!techName) {
|
|
5490
5572
|
const techList = Spacestationtechnology.map(
|
|
5491
5573
|
(tech2) => `▸ ${tech2.techname} (最大等级 ${romanNumerals[tech2.maxLevel]})`
|
|
@@ -5495,8 +5577,10 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5495
5577
|
'使用 "科技 科技名称" 查看详细信息',
|
|
5496
5578
|
"====================",
|
|
5497
5579
|
...techList,
|
|
5498
|
-
"===================="
|
|
5499
|
-
|
|
5580
|
+
"====================",
|
|
5581
|
+
isIntelligenceOfficer && "※ 情报副官享受20%升级折扣"
|
|
5582
|
+
// 新增折扣提示
|
|
5583
|
+
].filter(Boolean).join("\n");
|
|
5500
5584
|
}
|
|
5501
5585
|
const tech = Spacestationtechnology.find(
|
|
5502
5586
|
(t) => t.techname === techName
|
|
@@ -5504,9 +5588,13 @@ ${passiveMessages.map((m) => `▸ ${m}`).join("\n")}`
|
|
|
5504
5588
|
if (!tech) return `❌ 无效科技名称,可用科技:
|
|
5505
5589
|
${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
5506
5590
|
const techDetails = tech.levels.map((level) => {
|
|
5591
|
+
const originalCost = level.cost;
|
|
5592
|
+
const discountedCost = isIntelligenceOfficer ? Math.floor(originalCost * 0.8) : originalCost;
|
|
5593
|
+
const costDesc = isIntelligenceOfficer ? `▸ 升级花费:${discountedCost}金币 (原价${originalCost})` : `▸ 升级花费:${originalCost}金币`;
|
|
5507
5594
|
return [
|
|
5508
5595
|
`✦ 等级 ${romanNumerals[level.level]}`,
|
|
5509
|
-
|
|
5596
|
+
costDesc,
|
|
5597
|
+
// 修改后的价格显示
|
|
5510
5598
|
`▸ 基础效果:${level.description}`,
|
|
5511
5599
|
`💼 ${level.careerBonus}`,
|
|
5512
5600
|
"------------------"
|
|
@@ -5518,16 +5606,14 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5518
5606
|
'使用 "升级 科技名称" 进行升级',
|
|
5519
5607
|
"====================",
|
|
5520
5608
|
...techDetails,
|
|
5521
|
-
"===================="
|
|
5522
|
-
|
|
5609
|
+
"====================",
|
|
5610
|
+
isIntelligenceOfficer && "※ 情报副官享受20%升级折扣"
|
|
5611
|
+
// 新增折扣提示
|
|
5612
|
+
].filter(Boolean).join("\n");
|
|
5523
5613
|
});
|
|
5524
5614
|
ctx.command("ggcevo/挖矿").action(async ({ session }) => {
|
|
5525
|
-
const convertUTCtoChinaTime2 = /* @__PURE__ */ __name((utcDate) => {
|
|
5526
|
-
const chinaOffset = 8 * 60 * 60 * 1e3;
|
|
5527
|
-
return new Date(utcDate.getTime() + chinaOffset);
|
|
5528
|
-
}, "convertUTCtoChinaTime");
|
|
5529
5615
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5530
|
-
if (!profile) return "🔒
|
|
5616
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5531
5617
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5532
5618
|
if (await ctx.database.get("ggcevo_blacklist", { handle }).then((r) => r.length)) {
|
|
5533
5619
|
return "⛔ 您已被列入黑名单";
|
|
@@ -5552,8 +5638,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5552
5638
|
return "⛏️ 挖矿作业已开始,至少1小时后可收获。";
|
|
5553
5639
|
}
|
|
5554
5640
|
const nowtime = /* @__PURE__ */ new Date();
|
|
5555
|
-
const chinaStart =
|
|
5556
|
-
const chinaNow =
|
|
5641
|
+
const chinaStart = convertUTCtoChinaTime(record.startTime);
|
|
5642
|
+
const chinaNow = convertUTCtoChinaTime(nowtime);
|
|
5557
5643
|
const duration = Math.floor(
|
|
5558
5644
|
(chinaNow.getTime() - chinaStart.getTime()) / 1e3 / 60
|
|
5559
5645
|
);
|
|
@@ -5564,7 +5650,7 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5564
5650
|
`🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5565
5651
|
`⏱️ 当前时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5566
5652
|
`⏳ 还需等待:${remaining}分钟`,
|
|
5567
|
-
`💡
|
|
5653
|
+
`💡 提示:挖矿1小时后可随时收获并自动开始下一轮`
|
|
5568
5654
|
].join("\n");
|
|
5569
5655
|
}
|
|
5570
5656
|
const halfHours = Math.floor(duration / 30);
|
|
@@ -5602,11 +5688,8 @@ ${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
|
5602
5688
|
`🕒 开始时间:${record.startTime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5603
5689
|
`⏱️ 结束时间:${nowtime.toLocaleString("zh-CN", { hour12: false })}`,
|
|
5604
5690
|
`⏳ 持续时间:${formatTime(duration)}`,
|
|
5605
|
-
...tech.level >= 4 ? (
|
|
5606
|
-
// 仅当科技等级≥3时显示加成信息
|
|
5607
|
-
[`🔧 科技加成(Lv.${tech.level}):+${multiplier * 100}%`]
|
|
5608
|
-
) : [],
|
|
5609
5691
|
`💰 实际获得:${total}金币`,
|
|
5692
|
+
...tech.level >= 4 ? [`🔧 挖矿系统 Lv.${tech.level}:金币+${multiplier * 100}%`] : [],
|
|
5610
5693
|
"💡 已自动开始下一轮挖矿"
|
|
5611
5694
|
].join("\n");
|
|
5612
5695
|
});
|