koishi-plugin-ggcevo-game 1.2.72 → 1.2.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +556 -191
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -408,6 +408,14 @@ function apply(ctx, config) {
|
|
|
408
408
|
price: 0,
|
|
409
409
|
redCrystalCost: 30,
|
|
410
410
|
effects: "当主宰为“空间站感染虫”时才能使用,对“空间站哨枪塔”造成其当前血量值的伤害(获得等同于伤害值的金币)"
|
|
411
|
+
},
|
|
412
|
+
"闪光弹": {
|
|
413
|
+
id: 2,
|
|
414
|
+
type: "手榴弹",
|
|
415
|
+
description: "非致命军用炸药",
|
|
416
|
+
price: 75,
|
|
417
|
+
redCrystalCost: 0,
|
|
418
|
+
effects: "对目标使用后,清空其累计技能计数"
|
|
411
419
|
}
|
|
412
420
|
};
|
|
413
421
|
const modConfig = {
|
|
@@ -696,7 +704,7 @@ function apply(ctx, config) {
|
|
|
696
704
|
},
|
|
697
705
|
{
|
|
698
706
|
professionName: "情报副官",
|
|
699
|
-
effect: "
|
|
707
|
+
effect: "",
|
|
700
708
|
requirements: "拥有500枚金币",
|
|
701
709
|
Jobtransfer: false,
|
|
702
710
|
costcoins: 3e3
|
|
@@ -749,7 +757,7 @@ function apply(ctx, config) {
|
|
|
749
757
|
},
|
|
750
758
|
{
|
|
751
759
|
professionName: "枪手",
|
|
752
|
-
effect: "武器等级上限为7
|
|
760
|
+
effect: "武器等级上限为7级",
|
|
753
761
|
requirements: "拥有2把武器等级为6的武器",
|
|
754
762
|
Jobtransfer: false,
|
|
755
763
|
costcoins: 0,
|
|
@@ -832,74 +840,78 @@ function apply(ctx, config) {
|
|
|
832
840
|
{
|
|
833
841
|
techId: 1,
|
|
834
842
|
techname: "采掘系统",
|
|
843
|
+
careerNames: ["深空矿工", "情报副官"],
|
|
844
|
+
// 新增职业名称字段
|
|
835
845
|
maxLevel: 5,
|
|
836
846
|
levels: [
|
|
837
847
|
{
|
|
838
848
|
level: 1,
|
|
839
849
|
cost: 500,
|
|
840
|
-
description: "
|
|
841
|
-
careerBonus: "深空矿工/情报副官:
|
|
850
|
+
description: "提高挖矿效率,每日签到金币奖励+5%",
|
|
851
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+10%"
|
|
842
852
|
},
|
|
843
853
|
{
|
|
844
854
|
level: 2,
|
|
845
855
|
cost: 1750,
|
|
846
|
-
description: "
|
|
847
|
-
careerBonus: "深空矿工/情报副官:
|
|
856
|
+
description: "提高挖矿效率,每日签到金币奖励+10%",
|
|
857
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+20%,解锁专属“挖矿”权限"
|
|
848
858
|
},
|
|
849
859
|
{
|
|
850
860
|
level: 3,
|
|
851
861
|
cost: 2950,
|
|
852
|
-
description: "
|
|
853
|
-
careerBonus: "深空矿工/情报副官:
|
|
862
|
+
description: "提高挖矿效率,每日签到金币奖励+15%",
|
|
863
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+30%,解锁专属“挖矿”权限,并且挖矿效率提高10%"
|
|
854
864
|
},
|
|
855
865
|
{
|
|
856
866
|
level: 4,
|
|
857
867
|
cost: 4250,
|
|
858
|
-
description: "
|
|
859
|
-
careerBonus: "深空矿工/情报副官:
|
|
868
|
+
description: "提高挖矿效率,每日签到金币奖励+20%",
|
|
869
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+40%,解锁专属“挖矿”权限,并且挖矿效率提高20%"
|
|
860
870
|
},
|
|
861
871
|
{
|
|
862
872
|
level: 5,
|
|
863
873
|
cost: 5375,
|
|
864
|
-
description: "
|
|
865
|
-
careerBonus: "深空矿工/情报副官:
|
|
874
|
+
description: "提高挖矿效率,每日签到金币奖励+25%",
|
|
875
|
+
careerBonus: "深空矿工/情报副官: 每日签到金币奖励+50%,解锁专属“挖矿”权限,并且挖矿效率提高30%"
|
|
866
876
|
}
|
|
867
877
|
]
|
|
868
878
|
},
|
|
869
879
|
{
|
|
870
880
|
techId: 2,
|
|
871
881
|
techname: "武器系统",
|
|
882
|
+
careerNames: ["武器中士", "情报副官"],
|
|
883
|
+
// 新增职业名称字段
|
|
872
884
|
maxLevel: 5,
|
|
873
885
|
levels: [
|
|
874
886
|
{
|
|
875
887
|
level: 1,
|
|
876
888
|
cost: 500,
|
|
877
|
-
description: "
|
|
878
|
-
careerBonus: "武器中士/情报副官:
|
|
889
|
+
description: "提升空间站武器等级,升级武器享有5%的折扣",
|
|
890
|
+
careerBonus: "武器中士/情报副官: 升级武器享有10%的折扣"
|
|
879
891
|
},
|
|
880
892
|
{
|
|
881
893
|
level: 2,
|
|
882
894
|
cost: 1500,
|
|
883
|
-
description: "
|
|
884
|
-
careerBonus: "武器中士/情报副官:
|
|
895
|
+
description: "提升空间站武器等级,升级武器享有10%的折扣",
|
|
896
|
+
careerBonus: "武器中士/情报副官: 升级武器享有20%的折扣,购买武器享有10%的折扣(非传奇)"
|
|
885
897
|
},
|
|
886
898
|
{
|
|
887
899
|
level: 3,
|
|
888
900
|
cost: 2550,
|
|
889
|
-
description: "
|
|
890
|
-
careerBonus: "武器中士/情报副官:
|
|
901
|
+
description: "提升空间站武器等级,升级武器享有15%的折扣",
|
|
902
|
+
careerBonus: "武器中士/情报副官: 升级武器享有30%的折扣,购买武器享有15%的折扣(非传奇)"
|
|
891
903
|
},
|
|
892
904
|
{
|
|
893
905
|
level: 4,
|
|
894
906
|
cost: 3950,
|
|
895
|
-
description: "
|
|
896
|
-
careerBonus: "武器中士/情报副官:
|
|
907
|
+
description: "提升空间站武器等级,升级武器享有20%的折扣",
|
|
908
|
+
careerBonus: "武器中士/情报副官: 在升级武器享有40%的折扣,购买武器享有20%的折扣(非传奇)"
|
|
897
909
|
},
|
|
898
910
|
{
|
|
899
911
|
level: 5,
|
|
900
912
|
cost: 4650,
|
|
901
|
-
description: "
|
|
902
|
-
careerBonus: "武器中士/情报副官:
|
|
913
|
+
description: "提升空间站武器等级,升级武器享有25%的折扣,可以以原价购买传奇武器(仅限一把)",
|
|
914
|
+
careerBonus: "武器中士/情报副官: 升级武器享有50%的折扣,购买武器享有25%的折扣(非传奇),可以以80%的价格购买传奇武器(仅限一把)"
|
|
903
915
|
}
|
|
904
916
|
]
|
|
905
917
|
}
|
|
@@ -932,31 +944,25 @@ function apply(ctx, config) {
|
|
|
932
944
|
return { totalModAdd, hasCrit };
|
|
933
945
|
}
|
|
934
946
|
__name(calculateModifiers, "calculateModifiers");
|
|
935
|
-
async function calculateTagMultiplier(weaponData,
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
const bossTags = Array.isArray(bossRecord[0].tags) ? bossRecord[0].tags : JSON.parse(bossRecord[0].tags || "[]");
|
|
947
|
+
async function calculateTagMultiplier(weaponData, tags, equippedWeapon) {
|
|
948
|
+
const MOD_EFFECTS = [
|
|
949
|
+
{ mod: "裂甲核心", tag: "重甲", value: 1.2 },
|
|
950
|
+
{ mod: "助燃核心", tag: "惧热", value: 4 }
|
|
951
|
+
];
|
|
941
952
|
let totalAdditive = 0;
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
effectValue = 4;
|
|
948
|
-
} else {
|
|
949
|
-
effectValue = weaponData.tagEffects?.[tag] ?? 1;
|
|
950
|
-
}
|
|
953
|
+
for (const tag of tags) {
|
|
954
|
+
const activeMod = MOD_EFFECTS.find(
|
|
955
|
+
(me) => me.tag === tag && equippedWeapon.installedMods?.includes(me.mod)
|
|
956
|
+
);
|
|
957
|
+
const effectValue = activeMod ? activeMod.value : weaponData.tagEffects?.[tag] ?? 1;
|
|
951
958
|
totalAdditive += effectValue - 1;
|
|
952
|
-
}
|
|
959
|
+
}
|
|
953
960
|
return totalAdditive;
|
|
954
961
|
}
|
|
955
962
|
__name(calculateTagMultiplier, "calculateTagMultiplier");
|
|
956
|
-
function calculatePassiveEffects(
|
|
963
|
+
function calculatePassiveEffects(passives) {
|
|
957
964
|
let passiveEffect = 0;
|
|
958
|
-
|
|
959
|
-
effectivePassives.forEach((passive) => {
|
|
965
|
+
passives.forEach((passive) => {
|
|
960
966
|
const effect = passiveConfig[passive]?.effect || 0;
|
|
961
967
|
passiveEffect += effect;
|
|
962
968
|
});
|
|
@@ -1003,8 +1009,10 @@ function apply(ctx, config) {
|
|
|
1003
1009
|
return Math.floor(rankRecord.rank / 400) * 0.01;
|
|
1004
1010
|
}
|
|
1005
1011
|
__name(calculateRankBonus, "calculateRankBonus");
|
|
1006
|
-
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss) {
|
|
1012
|
+
async function calculateTotalDamage(ctx2, session, equippedWeapon, targetBoss, options) {
|
|
1007
1013
|
let effectMessage = [];
|
|
1014
|
+
const finalTags = options?.customTags || targetBoss.tags || [];
|
|
1015
|
+
const finalPassives = options?.customPassives || targetBoss.skills || [];
|
|
1008
1016
|
const [profile] = await ctx2.database.get("sc2arcade_player", { userId: session.userId });
|
|
1009
1017
|
const { regionId, realmId, profileId } = profile;
|
|
1010
1018
|
const handle = `${regionId}-S2-${realmId}-${profileId}`;
|
|
@@ -1027,10 +1035,9 @@ function apply(ctx, config) {
|
|
|
1027
1035
|
if (critRhythmEffect) {
|
|
1028
1036
|
effectMessage.push("🎵 暴击韵律祈愿生效(暴击率+20%)");
|
|
1029
1037
|
}
|
|
1030
|
-
const
|
|
1031
|
-
const tagMultiplier = await calculateTagMultiplier(weaponData, targetBossConfig, equippedWeapon);
|
|
1038
|
+
const tagMultiplier = await calculateTagMultiplier(weaponData, finalTags, equippedWeapon);
|
|
1032
1039
|
damage *= 1 + tagMultiplier;
|
|
1033
|
-
const passiveMultiplier = calculatePassiveEffects(
|
|
1040
|
+
const passiveMultiplier = calculatePassiveEffects(finalPassives);
|
|
1034
1041
|
damage *= 1 + passiveMultiplier;
|
|
1035
1042
|
const { damage: careerDamage, message: careerMessage } = await calculateCareerBonus(
|
|
1036
1043
|
ctx2,
|
|
@@ -1835,12 +1842,20 @@ function apply(ctx, config) {
|
|
|
1835
1842
|
}
|
|
1836
1843
|
}
|
|
1837
1844
|
__name(checkTransferRequirements, "checkTransferRequirements");
|
|
1838
|
-
async function applyItemEffect(session, handle, itemConfig2) {
|
|
1839
|
-
const itemName = Object.entries(SyndicatedItems).find(
|
|
1840
|
-
([_, item]) => item.id === itemConfig2.id
|
|
1841
|
-
)?.[0] || "未知物品";
|
|
1845
|
+
async function applyItemEffect(session, handle, itemConfig2, target) {
|
|
1842
1846
|
try {
|
|
1847
|
+
const itemName = Object.entries(SyndicatedItems).find(
|
|
1848
|
+
([_, item]) => item.id === itemConfig2.id
|
|
1849
|
+
)?.[0] || "未知物品";
|
|
1843
1850
|
if (itemConfig2.id === 1) {
|
|
1851
|
+
const activeSentry = await ctx.database.get("ggcevo_boss", {
|
|
1852
|
+
name: "空间站哨枪塔",
|
|
1853
|
+
isActive: true
|
|
1854
|
+
});
|
|
1855
|
+
if (!activeSentry.length) return {
|
|
1856
|
+
success: false,
|
|
1857
|
+
message: "⚠️ 目标「空间站哨枪塔」未激活"
|
|
1858
|
+
};
|
|
1844
1859
|
const [SentryTower] = await ctx.database.get("ggcevo_boss", {
|
|
1845
1860
|
name: "空间站哨枪塔",
|
|
1846
1861
|
isActive: true
|
|
@@ -1849,39 +1864,179 @@ function apply(ctx, config) {
|
|
|
1849
1864
|
await ctx.database.set(
|
|
1850
1865
|
"ggcevo_boss",
|
|
1851
1866
|
{ name: "空间站哨枪塔" },
|
|
1852
|
-
{
|
|
1853
|
-
isActive: false,
|
|
1854
|
-
HP: 0
|
|
1855
|
-
}
|
|
1867
|
+
{ isActive: false, HP: 0 }
|
|
1856
1868
|
);
|
|
1857
1869
|
await ctx.database.withTransaction(async () => {
|
|
1858
1870
|
const signRecords = await ctx.database.get("ggcevo_sign", { handle });
|
|
1859
|
-
const currentRewards = signRecords[0]?.totalRewards || 0;
|
|
1860
1871
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
1861
1872
|
handle,
|
|
1862
|
-
totalRewards:
|
|
1873
|
+
totalRewards: (signRecords[0]?.totalRewards || 0) + damageValue
|
|
1863
1874
|
}], ["handle"]);
|
|
1864
1875
|
const damageRecords = await ctx.database.get("ggcevo_boss_damage", { handle });
|
|
1865
|
-
const currentDamage = damageRecords[0]?.totalDamage || 0;
|
|
1866
|
-
const currentCount = damageRecords[0]?.attackCount || 0;
|
|
1867
1876
|
await ctx.database.upsert("ggcevo_boss_damage", [{
|
|
1868
1877
|
handle,
|
|
1869
1878
|
playerName: session.username,
|
|
1870
|
-
totalDamage:
|
|
1871
|
-
attackCount:
|
|
1872
|
-
// 保持原攻击次数
|
|
1879
|
+
totalDamage: (damageRecords[0]?.totalDamage || 0) + damageValue,
|
|
1880
|
+
attackCount: damageRecords[0]?.attackCount || 0,
|
|
1873
1881
|
bossGroupId: 4
|
|
1874
1882
|
}], ["handle"]);
|
|
1875
1883
|
});
|
|
1876
|
-
return
|
|
1884
|
+
return {
|
|
1885
|
+
success: true,
|
|
1886
|
+
message: `成功引爆${itemName},造成 ${damageValue} 点伤害,获得等额金币`
|
|
1887
|
+
};
|
|
1877
1888
|
}
|
|
1878
|
-
|
|
1889
|
+
if (itemConfig2.id === 2) {
|
|
1890
|
+
if (!target) return {
|
|
1891
|
+
success: false,
|
|
1892
|
+
message: "该武器使用需要选择合适的目标。"
|
|
1893
|
+
};
|
|
1894
|
+
const targetboss = await ctx.database.get("ggcevo_boss", {
|
|
1895
|
+
name: target,
|
|
1896
|
+
isActive: true
|
|
1897
|
+
});
|
|
1898
|
+
if (!targetboss.length || targetboss[0].Skillcountpoints === 0) return {
|
|
1899
|
+
success: false,
|
|
1900
|
+
message: "您选择的不是合法目标(目标未存活/目标无技能计数)。"
|
|
1901
|
+
};
|
|
1902
|
+
await ctx.database.set(
|
|
1903
|
+
"ggcevo_boss",
|
|
1904
|
+
{ name: target },
|
|
1905
|
+
{ Skillcountpoints: 0 }
|
|
1906
|
+
);
|
|
1907
|
+
return {
|
|
1908
|
+
success: true,
|
|
1909
|
+
message: `成功使用${itemName},您的目标${target}已重置其技能计数`
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
return {
|
|
1913
|
+
success: true,
|
|
1914
|
+
message: `${itemName} 效果已生效(开发中)`
|
|
1915
|
+
};
|
|
1879
1916
|
} catch (error) {
|
|
1880
1917
|
console.error("物品效果处理失败:", error);
|
|
1881
|
-
return
|
|
1918
|
+
return {
|
|
1919
|
+
success: false,
|
|
1920
|
+
message: "⚠️ 物品效果处理异常,已回滚操作"
|
|
1921
|
+
};
|
|
1882
1922
|
}
|
|
1883
1923
|
}
|
|
1884
1924
|
__name(applyItemEffect, "applyItemEffect");
|
|
1925
|
+
async function handleTechUpgrade(handle, target) {
|
|
1926
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
1927
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
1928
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
1929
|
+
}
|
|
1930
|
+
const tech = Spacestationtechnology.find(
|
|
1931
|
+
(t) => t.techname === target || t.techId == target
|
|
1932
|
+
);
|
|
1933
|
+
const [techEntry] = await ctx.database.get("ggcevo_tech", { handle, techId: tech.techId });
|
|
1934
|
+
const currentLevel = techEntry?.level || 0;
|
|
1935
|
+
if (currentLevel >= tech.maxLevel) return `❌ ${tech.techname}已达最高等级`;
|
|
1936
|
+
const nextLevel = currentLevel + 1;
|
|
1937
|
+
const levelData = tech.levels.find((l) => l.level === nextLevel);
|
|
1938
|
+
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1939
|
+
if (signInfo?.totalRewards < levelData.cost) {
|
|
1940
|
+
return `❌ 需要 ${levelData.cost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
1941
|
+
}
|
|
1942
|
+
await ctx.database.withTransaction(async () => {
|
|
1943
|
+
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
1944
|
+
totalRewards: signInfo.totalRewards - levelData.cost
|
|
1945
|
+
});
|
|
1946
|
+
await ctx.database.upsert("ggcevo_tech", [{
|
|
1947
|
+
handle,
|
|
1948
|
+
techId: tech.techId,
|
|
1949
|
+
level: nextLevel
|
|
1950
|
+
}], ["handle", "techId"]);
|
|
1951
|
+
});
|
|
1952
|
+
return `✅ ${tech.techname} 升级至 Lv.${nextLevel}
|
|
1953
|
+
📝 ${levelData.description}
|
|
1954
|
+
💼 ${levelData.careerBonus}`;
|
|
1955
|
+
}
|
|
1956
|
+
__name(handleTechUpgrade, "handleTechUpgrade");
|
|
1957
|
+
async function handleWeaponUpgrade(handle, target) {
|
|
1958
|
+
const weaponData = weaponConfig[target];
|
|
1959
|
+
const [equipment] = await ctx.database.get("ggcevo_equipment", {
|
|
1960
|
+
handle,
|
|
1961
|
+
weaponId: weaponData.id
|
|
1962
|
+
});
|
|
1963
|
+
if (!equipment) return "❌ 尚未获得该武器";
|
|
1964
|
+
if (equipment.level >= 6) return "❌ 武器已达最高等级";
|
|
1965
|
+
const BASE_COST = [1050, 1450, 1850, 2250, 2650, 3050];
|
|
1966
|
+
const baseCost = BASE_COST[equipment.level];
|
|
1967
|
+
const weaponTechConfig = Spacestationtechnology.find((t) => t.techId === 2);
|
|
1968
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
1969
|
+
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 }).catch(() => [{ level: 0 }]);
|
|
1970
|
+
const techLevel = Math.min(Math.max(weaponTech?.level || 0, 0), 5);
|
|
1971
|
+
const isCareerMatch = weaponTechConfig?.careerNames.includes(careerData?.career);
|
|
1972
|
+
const BASE_DISCOUNTS = [5, 10, 15, 20, 25];
|
|
1973
|
+
const CAREER_DISCOUNTS = [10, 20, 30, 40, 50];
|
|
1974
|
+
const baseDiscount = techLevel > 0 ? BASE_DISCOUNTS[techLevel - 1] : 0;
|
|
1975
|
+
const careerDiscount = isCareerMatch && techLevel > 0 ? CAREER_DISCOUNTS[techLevel - 1] : 0;
|
|
1976
|
+
const weaponDiscount = Math.max(baseDiscount, careerDiscount) / 100;
|
|
1977
|
+
let discountedCost = baseCost * (1 - weaponDiscount);
|
|
1978
|
+
const activeWish = await checkFoxBlessing(handle);
|
|
1979
|
+
if (activeWish) {
|
|
1980
|
+
discountedCost *= 0.8;
|
|
1981
|
+
}
|
|
1982
|
+
const actualCost = Math.floor(discountedCost);
|
|
1983
|
+
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
1984
|
+
if (signInfo?.totalRewards < actualCost) {
|
|
1985
|
+
return `❌ 需要 ${actualCost} 金币,当前持有:${signInfo?.totalRewards || 0}`;
|
|
1986
|
+
}
|
|
1987
|
+
await ctx.database.withTransaction(async () => {
|
|
1988
|
+
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
1989
|
+
totalRewards: signInfo.totalRewards - actualCost
|
|
1990
|
+
});
|
|
1991
|
+
await ctx.database.set(
|
|
1992
|
+
"ggcevo_equipment",
|
|
1993
|
+
{ handle, weaponId: weaponData.id },
|
|
1994
|
+
{
|
|
1995
|
+
level: equipment.level + 1,
|
|
1996
|
+
modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
|
|
1997
|
+
}
|
|
1998
|
+
);
|
|
1999
|
+
if (activeWish) {
|
|
2000
|
+
await ctx.database.set(
|
|
2001
|
+
"ggcevo_Wish_Record",
|
|
2002
|
+
{ id: activeWish.id },
|
|
2003
|
+
{ isused: true }
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
});
|
|
2007
|
+
const newLevel = equipment.level + 1;
|
|
2008
|
+
const damage = (weaponData.damage * (1 + 0.1 * newLevel)).toFixed(1);
|
|
2009
|
+
let msg = `${target} 升级成功!Lv.${newLevel}`;
|
|
2010
|
+
msg += `
|
|
2011
|
+
💸 消耗:${actualCost}金币 (原价${baseCost})`;
|
|
2012
|
+
let discountDetails = [];
|
|
2013
|
+
if (weaponDiscount > 0) {
|
|
2014
|
+
discountDetails.push(`武器系统 Lv${techLevel} 折扣:${Math.max(baseDiscount, careerDiscount)}%`);
|
|
2015
|
+
}
|
|
2016
|
+
if (activeWish) {
|
|
2017
|
+
discountDetails.push("灵狐升运折扣:20%");
|
|
2018
|
+
}
|
|
2019
|
+
if (discountDetails.length > 0) {
|
|
2020
|
+
msg += `
|
|
2021
|
+
🔧 已应用折扣:${discountDetails.join(" + ")}`;
|
|
2022
|
+
}
|
|
2023
|
+
msg += `
|
|
2024
|
+
💥 伤害:${damage}`;
|
|
2025
|
+
msg += `
|
|
2026
|
+
🔩 改装槽:${Math.floor(newLevel / 3) + 1}个`;
|
|
2027
|
+
return msg;
|
|
2028
|
+
}
|
|
2029
|
+
__name(handleWeaponUpgrade, "handleWeaponUpgrade");
|
|
2030
|
+
async function checkFoxBlessing(handle) {
|
|
2031
|
+
return ctx.database.get("ggcevo_Wish_Record", {
|
|
2032
|
+
handle,
|
|
2033
|
+
wishname: "灵狐升运",
|
|
2034
|
+
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
2035
|
+
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
2036
|
+
isused: false
|
|
2037
|
+
}).then((records) => records[0]);
|
|
2038
|
+
}
|
|
2039
|
+
__name(checkFoxBlessing, "checkFoxBlessing");
|
|
1885
2040
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
1886
2041
|
const session = argv.session;
|
|
1887
2042
|
let winCount = 0;
|
|
@@ -2109,17 +2264,41 @@ ${itemDetails.join("\n")}`;
|
|
|
2109
2264
|
}
|
|
2110
2265
|
let redCrystal = 0;
|
|
2111
2266
|
let careerCrystalMessage = "";
|
|
2112
|
-
if (meowEffect) {
|
|
2113
|
-
tickets *= 2;
|
|
2114
|
-
points *= 2;
|
|
2115
|
-
effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励!";
|
|
2116
|
-
}
|
|
2117
|
-
let careerMessage = "";
|
|
2118
2267
|
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
2268
|
+
let miningBonus = 0;
|
|
2269
|
+
let miningMessage = "";
|
|
2270
|
+
const BASE_BONUS = [5, 10, 15, 20, 25];
|
|
2271
|
+
const CAREER_BONUS = [10, 20, 30, 40, 50];
|
|
2272
|
+
const miningTechConfig = Spacestationtechnology.find((t) => t.techId === 1);
|
|
2273
|
+
if (miningTechConfig) {
|
|
2274
|
+
const [userMiningTech] = await ctx.database.get("ggcevo_tech", {
|
|
2275
|
+
handle,
|
|
2276
|
+
techId: 1
|
|
2277
|
+
}).catch(() => [{ level: 0 }]);
|
|
2278
|
+
const techLevel = Math.min(Math.max(userMiningTech?.level || 0, 0), 5);
|
|
2279
|
+
const baseBonus = techLevel > 0 ? BASE_BONUS[techLevel - 1] : 0;
|
|
2280
|
+
let careerTechBonus = 0;
|
|
2281
|
+
if (careerData?.career && miningTechConfig.careerNames.includes(careerData.career)) {
|
|
2282
|
+
careerTechBonus = techLevel > 0 ? CAREER_BONUS[techLevel - 1] : 0;
|
|
2283
|
+
}
|
|
2284
|
+
miningBonus = Math.max(baseBonus, careerTechBonus);
|
|
2285
|
+
if (miningBonus > 0) {
|
|
2286
|
+
miningMessage = `
|
|
2287
|
+
⚙️ 采掘系统 Lv${techLevel} 金币加成:+${miningBonus}%`;
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
let minerBonus = 0;
|
|
2291
|
+
let minerMessage = "";
|
|
2119
2292
|
if (careerData?.career === "深空矿工") {
|
|
2120
|
-
|
|
2121
|
-
|
|
2293
|
+
minerBonus = 50;
|
|
2294
|
+
minerMessage = `
|
|
2295
|
+
⛏️ 深空矿工职业加成:金币+50%`;
|
|
2122
2296
|
}
|
|
2297
|
+
const totalBonus = miningBonus + minerBonus;
|
|
2298
|
+
if (totalBonus > 0) {
|
|
2299
|
+
points = Math.round(points * (1 + totalBonus / 100));
|
|
2300
|
+
}
|
|
2301
|
+
const bonusMessage = miningMessage + minerMessage;
|
|
2123
2302
|
if (careerData?.group === "辛迪加海盗" && careerData.career === "辛迪加财务经理") {
|
|
2124
2303
|
if (monthlyDays < 7) {
|
|
2125
2304
|
redCrystal = 1;
|
|
@@ -2135,6 +2314,11 @@ ${itemDetails.join("\n")}`;
|
|
|
2135
2314
|
careerCrystalMessage = `
|
|
2136
2315
|
⚓ 辛迪加财务经理职业加成:获得 ${redCrystal} 红晶`;
|
|
2137
2316
|
}
|
|
2317
|
+
if (meowEffect) {
|
|
2318
|
+
tickets *= 2;
|
|
2319
|
+
points *= 2;
|
|
2320
|
+
effectMessage = "\n🐾 喵喵财源祈愿生效,获得双倍奖励(金币和咕咕币)!";
|
|
2321
|
+
}
|
|
2138
2322
|
await ctx.database.withTransaction(async () => {
|
|
2139
2323
|
await ctx.database.upsert("ggcevo_sign", [{
|
|
2140
2324
|
handle,
|
|
@@ -2156,7 +2340,7 @@ ${itemDetails.join("\n")}`;
|
|
|
2156
2340
|
});
|
|
2157
2341
|
return `签到成功!本月累计签到${monthlyDays}天,获得:
|
|
2158
2342
|
💰 金币 x ${points}
|
|
2159
|
-
🪙 咕咕币 x ${tickets}` + effectMessage +
|
|
2343
|
+
🪙 咕咕币 x ${tickets}` + (effectMessage || "") + bonusMessage + (careerCrystalMessage || "");
|
|
2160
2344
|
} catch (error) {
|
|
2161
2345
|
console.error("签到命令时发生错误:", error);
|
|
2162
2346
|
return "服务器繁忙,请稍后尝试。";
|
|
@@ -3542,7 +3726,9 @@ ${achievementList.join("\n")}`;
|
|
|
3542
3726
|
day: "2-digit"
|
|
3543
3727
|
})}`;
|
|
3544
3728
|
});
|
|
3545
|
-
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async (
|
|
3729
|
+
ctx.command("ggcevo/武器库 [type]").usage("输入“武器库”查看类型,或“武器库 类型”查看详细武器信息").action(async ({ session }, type) => {
|
|
3730
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3731
|
+
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
3546
3732
|
const typeStats = Object.values(weaponConfig).filter((weapon) => weapon.price !== 0).reduce((stats, weapon) => {
|
|
3547
3733
|
stats[weapon.type] = (stats[weapon.type] || 0) + 1;
|
|
3548
3734
|
return stats;
|
|
@@ -3561,7 +3747,7 @@ ${achievementList.join("\n")}`;
|
|
|
3561
3747
|
return `无效武器类型,可用类型:
|
|
3562
3748
|
${validTypes.join("、")}`;
|
|
3563
3749
|
}
|
|
3564
|
-
const items = Object.entries(weaponConfig).filter(([
|
|
3750
|
+
const items = Object.entries(weaponConfig).filter(([_, config2]) => config2.type === type && config2.price !== 0).map(([name2, config2]) => {
|
|
3565
3751
|
const tagEffectsDesc = config2.tagEffects ? Object.entries(config2.tagEffects).map(([tag, multiplier]) => `▸ 对${tag}目标造成${(multiplier * 100).toFixed(0)}%伤害`).join("\n") : "▸ 无特殊加成效果";
|
|
3566
3752
|
return [
|
|
3567
3753
|
`【${name2}】`,
|
|
@@ -3581,46 +3767,115 @@ ${validTypes.join("、")}`;
|
|
|
3581
3767
|
items.length === 0 ? "⚠️ 该分类下暂无可用武器" : ""
|
|
3582
3768
|
].join("\n\n");
|
|
3583
3769
|
});
|
|
3584
|
-
ctx.command("ggcevo
|
|
3770
|
+
ctx.command("ggcevo/爆破库 [type]").usage("输入“爆破库”查看分类,或“爆破库 类型”查看详细物品").action(async ({ session }, type) => {
|
|
3771
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3772
|
+
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
3773
|
+
const filteredItems = Object.values(SyndicatedItems).filter(
|
|
3774
|
+
(item) => item.price > 0 && ["爆破物", "手榴弹"].includes(item.type)
|
|
3775
|
+
);
|
|
3776
|
+
const typeStats = filteredItems.reduce((stats, item) => {
|
|
3777
|
+
stats[item.type] = (stats[item.type] || 0) + 1;
|
|
3778
|
+
return stats;
|
|
3779
|
+
}, {});
|
|
3780
|
+
if (!type) {
|
|
3781
|
+
return [
|
|
3782
|
+
"💣 爆破装备库分类 💣",
|
|
3783
|
+
'使用 "爆破库 类型名称" 查看详细列表',
|
|
3784
|
+
"====================",
|
|
3785
|
+
...Object.entries(typeStats).map(([typeName, count]) => `▸ ${typeName} (${count}种)`),
|
|
3786
|
+
"===================="
|
|
3787
|
+
].join("\n");
|
|
3788
|
+
}
|
|
3789
|
+
const validTypes = Object.keys(typeStats);
|
|
3790
|
+
if (!validTypes.includes(type)) {
|
|
3791
|
+
return `无效分类,可用类型:
|
|
3792
|
+
${validTypes.join("、")}`;
|
|
3793
|
+
}
|
|
3794
|
+
const items = filteredItems.filter((item) => item.type === type).map((item) => [
|
|
3795
|
+
`${Object.keys(SyndicatedItems).find((k) => SyndicatedItems[k] === item)}`,
|
|
3796
|
+
// 获取物品名称
|
|
3797
|
+
`类型:${item.type}`,
|
|
3798
|
+
`价格:${item.price}金币`,
|
|
3799
|
+
`效果:${item.effects}`,
|
|
3800
|
+
`描述:${item.description}`
|
|
3801
|
+
].join("\n"));
|
|
3802
|
+
return [
|
|
3803
|
+
`💣 爆破装备库 - ${type} 💣`,
|
|
3804
|
+
"使用“购买 物品名称”命令进行购买",
|
|
3805
|
+
"====================",
|
|
3806
|
+
...items,
|
|
3807
|
+
items.length === 0 ? "⚠️ 该分类下暂无可用物品" : ""
|
|
3808
|
+
].join("\n\n");
|
|
3809
|
+
});
|
|
3810
|
+
ctx.command("ggcevo/购买 <item>").action(async ({ session }, item) => {
|
|
3585
3811
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3586
3812
|
if (!profile) return "您暂未绑定句柄。";
|
|
3587
3813
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3588
3814
|
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
3589
|
-
if (existingEntries.length > 0)
|
|
3590
|
-
|
|
3815
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
3816
|
+
const allItems = { ...weaponConfig, ...SyndicatedItems };
|
|
3817
|
+
if (!item) return "请输入“购买 物品名称”来购买所需物品。";
|
|
3818
|
+
const config2 = allItems[item];
|
|
3819
|
+
if (!config2) return "无效的物品名称,请重新输入。";
|
|
3820
|
+
if (config2.price <= 0) return "❌ 该物品不可直接购买";
|
|
3821
|
+
const isWeapon = ["能量武器", "热能武器", "实弹武器"].includes(config2.type);
|
|
3822
|
+
if (isWeapon) {
|
|
3823
|
+
const existingWeapon = await ctx.database.get("ggcevo_equipment", {
|
|
3824
|
+
handle,
|
|
3825
|
+
weaponId: config2.id
|
|
3826
|
+
});
|
|
3827
|
+
if (existingWeapon.length > 0) return `❌ 您已经拥有${item},无法重复购买`;
|
|
3591
3828
|
}
|
|
3592
3829
|
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
if (
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3830
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
3831
|
+
const [weaponTech] = await ctx.database.get("ggcevo_tech", { handle, techId: 2 });
|
|
3832
|
+
let discountDetails = [];
|
|
3833
|
+
let totalDiscount = 0;
|
|
3834
|
+
if (isWeapon) {
|
|
3835
|
+
const techDiscountTable = {
|
|
3836
|
+
2: [0, 10],
|
|
3837
|
+
3: [0, 15],
|
|
3838
|
+
4: [0, 20],
|
|
3839
|
+
5: [0, 25]
|
|
3840
|
+
};
|
|
3841
|
+
const techLevel = weaponTech?.level || 0;
|
|
3842
|
+
if (techLevel >= 2) {
|
|
3843
|
+
const [baseDisc, careerDisc] = techDiscountTable[Math.min(techLevel, 5)] || [0, 0];
|
|
3844
|
+
const isQualifiedCareer = careerData?.career && Spacestationtechnology.find((t) => t.techId === 2)?.careerNames.includes(careerData.career);
|
|
3845
|
+
const techDiscount = isQualifiedCareer ? Math.max(baseDisc, careerDisc) : baseDisc;
|
|
3846
|
+
if (techDiscount > 0) {
|
|
3847
|
+
totalDiscount += techDiscount;
|
|
3848
|
+
discountDetails.push(
|
|
3849
|
+
`武器系统 Lv${techLevel}${isQualifiedCareer ? "(职业加成)" : ""} ${techDiscount}%折扣`
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3606
3853
|
}
|
|
3607
|
-
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
3854
|
+
const activeWish = isWeapon ? await ctx.database.get("ggcevo_Wish_Record", {
|
|
3608
3855
|
handle,
|
|
3609
3856
|
wishname: "蚱蜢优购",
|
|
3610
3857
|
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
3611
3858
|
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
3612
3859
|
isused: false
|
|
3613
|
-
}).then((records) => records[0]);
|
|
3614
|
-
let actualPrice = config2.price;
|
|
3615
|
-
let discountMessage = "";
|
|
3616
|
-
let equippedCount;
|
|
3860
|
+
}).then((records) => records[0]) : null;
|
|
3617
3861
|
if (activeWish) {
|
|
3618
|
-
|
|
3619
|
-
|
|
3862
|
+
const wishDiscount = 20;
|
|
3863
|
+
totalDiscount = 100 - (100 - totalDiscount) * (100 - wishDiscount) / 100;
|
|
3864
|
+
discountDetails.push(`蚱蜢优购祈愿生效 ${wishDiscount}%折扣`);
|
|
3865
|
+
}
|
|
3866
|
+
let actualPrice = config2.price;
|
|
3867
|
+
if (totalDiscount > 0) {
|
|
3868
|
+
actualPrice = Math.floor(config2.price * (100 - totalDiscount) / 100);
|
|
3869
|
+
actualPrice = Math.max(actualPrice, 1);
|
|
3620
3870
|
}
|
|
3621
3871
|
if ((signInfo?.totalRewards || 0) < actualPrice) {
|
|
3622
|
-
|
|
3872
|
+
let priceInfo = `需要 ${actualPrice} 金币`;
|
|
3873
|
+
if (discountDetails.length > 0) {
|
|
3874
|
+
priceInfo += `(原价 ${config2.price},累计折扣 ${totalDiscount}%)`;
|
|
3875
|
+
}
|
|
3876
|
+
return `❌ 金币不足,${priceInfo}`;
|
|
3623
3877
|
}
|
|
3878
|
+
let isAutoEquipped = false;
|
|
3624
3879
|
await ctx.database.withTransaction(async () => {
|
|
3625
3880
|
await ctx.database.set("ggcevo_sign", { handle }, {
|
|
3626
3881
|
totalRewards: signInfo.totalRewards - actualPrice
|
|
@@ -3630,32 +3885,55 @@ ${validTypes.join("、")}`;
|
|
|
3630
3885
|
isused: true
|
|
3631
3886
|
});
|
|
3632
3887
|
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3888
|
+
if (isWeapon) {
|
|
3889
|
+
await ctx.database.upsert("ggcevo_equipment", [{
|
|
3890
|
+
handle,
|
|
3891
|
+
weaponId: config2.id,
|
|
3892
|
+
level: 0,
|
|
3893
|
+
modificationSlots: 1,
|
|
3894
|
+
equipped: false
|
|
3895
|
+
}], ["handle", "weaponId"]);
|
|
3896
|
+
const equippedCount = await ctx.database.select("ggcevo_equipment").where({ handle, equipped: true }).execute((row) => import_koishi.$.count(row.weaponId));
|
|
3897
|
+
if (equippedCount === 0) {
|
|
3898
|
+
await ctx.database.set(
|
|
3899
|
+
"ggcevo_equipment",
|
|
3900
|
+
{ handle, weaponId: config2.id },
|
|
3901
|
+
{ equipped: true }
|
|
3902
|
+
);
|
|
3903
|
+
isAutoEquipped = true;
|
|
3904
|
+
}
|
|
3905
|
+
} else {
|
|
3906
|
+
const [existing] = await ctx.database.get("ggcevo_warehouse", {
|
|
3907
|
+
handle,
|
|
3908
|
+
itemId: config2.id
|
|
3909
|
+
});
|
|
3910
|
+
await ctx.database.upsert("ggcevo_warehouse", [{
|
|
3911
|
+
handle,
|
|
3912
|
+
itemId: config2.id,
|
|
3913
|
+
quantity: (existing?.quantity || 0) + 1
|
|
3914
|
+
}], ["handle", "itemId"]);
|
|
3647
3915
|
}
|
|
3648
3916
|
});
|
|
3649
|
-
let message =
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3917
|
+
let message = `✅ 成功获取 ${isWeapon ? "武器" : "物品"}「${item}」
|
|
3918
|
+
`;
|
|
3919
|
+
message += `花费 ${actualPrice} 金币`;
|
|
3920
|
+
if (discountDetails.length > 0) {
|
|
3921
|
+
message += `(原价 ${config2.price} 金币)
|
|
3922
|
+
折扣明细:
|
|
3923
|
+
▸ ${discountDetails.join("\n▸ ")}`;
|
|
3653
3924
|
}
|
|
3654
|
-
if (
|
|
3925
|
+
if (isWeapon) {
|
|
3926
|
+
if (isAutoEquipped) {
|
|
3927
|
+
message += "\n\n【系统已自动装备该武器】";
|
|
3928
|
+
}
|
|
3929
|
+
message += "\n输入「武器仓库」查看详情";
|
|
3930
|
+
} else {
|
|
3931
|
+
const [current] = await ctx.database.get("ggcevo_warehouse", { handle, itemId: config2.id });
|
|
3655
3932
|
message += `
|
|
3656
|
-
|
|
3933
|
+
|
|
3934
|
+
当前持有数量:${current?.quantity || 1},输入「仓库」查看物品`;
|
|
3657
3935
|
}
|
|
3658
|
-
return message
|
|
3936
|
+
return message;
|
|
3659
3937
|
});
|
|
3660
3938
|
ctx.command("ggcevo/武器仓库").action(async ({ session }) => {
|
|
3661
3939
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
@@ -3723,65 +4001,24 @@ ${validTypes.join("、")}`;
|
|
|
3723
4001
|
});
|
|
3724
4002
|
return `您已成功装备武器 ${weapon}!`;
|
|
3725
4003
|
});
|
|
3726
|
-
ctx.command("ggcevo/升级 <
|
|
4004
|
+
ctx.command("ggcevo/升级 <target>", "升级武器或科技").action(async ({ session }, target) => {
|
|
3727
4005
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
3728
|
-
if (!profile) return "
|
|
4006
|
+
if (!profile) return "❌ 您暂未绑定句柄";
|
|
3729
4007
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
return `❌ 拒绝访问,您已被列入黑名单。`;
|
|
3733
|
-
}
|
|
3734
|
-
const [signInfo] = await ctx.database.get("ggcevo_sign", { handle });
|
|
3735
|
-
const [equipment] = await ctx.database.get("ggcevo_equipment", {
|
|
3736
|
-
handle,
|
|
3737
|
-
weaponId: weaponConfig[weapon]?.id
|
|
3738
|
-
});
|
|
3739
|
-
if (!weapon) return "请输入“升级 武器名称”来升级你想要的武器。";
|
|
3740
|
-
if (!equipment) return "尚未获得该武器。";
|
|
3741
|
-
if (equipment.level >= 6) return "该武器已达最大升级等级。";
|
|
3742
|
-
const activeWish = await ctx.database.get("ggcevo_Wish_Record", {
|
|
3743
|
-
handle,
|
|
3744
|
-
wishname: "灵狐升运",
|
|
3745
|
-
startTime: { $lte: /* @__PURE__ */ new Date() },
|
|
3746
|
-
endTime: { $gte: /* @__PURE__ */ new Date() },
|
|
3747
|
-
isused: false
|
|
3748
|
-
}).then((records) => records[0]);
|
|
3749
|
-
let baseCost = [1050, 1450, 1850, 2250, 2650, 3050][equipment.level];
|
|
3750
|
-
let actualCost = baseCost;
|
|
3751
|
-
let discountMessage = "";
|
|
3752
|
-
if (activeWish) {
|
|
3753
|
-
actualCost = Math.floor(baseCost * 0.8);
|
|
3754
|
-
discountMessage = ` (祈愿优惠价,原价${baseCost})`;
|
|
4008
|
+
if ((await ctx.database.get("ggcevo_blacklist", { handle })).length) {
|
|
4009
|
+
return "❌ 拒绝访问,您已被列入黑名单";
|
|
3755
4010
|
}
|
|
3756
|
-
if (
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
}, {
|
|
3766
|
-
level: equipment.level + 1,
|
|
3767
|
-
modificationSlots: Math.floor((equipment.level + 1) / 3) + 1
|
|
3768
|
-
});
|
|
3769
|
-
if (activeWish) {
|
|
3770
|
-
await ctx.database.set("ggcevo_Wish_Record", { id: activeWish.id }, {
|
|
3771
|
-
isused: true
|
|
3772
|
-
});
|
|
3773
|
-
}
|
|
3774
|
-
});
|
|
3775
|
-
const newLevel = equipment.level + 1;
|
|
3776
|
-
const baseDamage = (weaponConfig[weapon].damage * (1 + 0.1 * newLevel)).toFixed(1);
|
|
3777
|
-
const slots = Math.floor(newLevel / 3) + 1;
|
|
3778
|
-
let message = `${weapon} 升级成功!花费${actualCost}枚金币${discountMessage}。`;
|
|
3779
|
-
if (activeWish) {
|
|
3780
|
-
message += `
|
|
3781
|
-
🦊 灵狐升运祈愿已使用,下次升级将恢复原价。`;
|
|
4011
|
+
if (!target) return "⚠️ 请输入要升级的武器或科技名称(升级科技需要加入人类联盟阵营)";
|
|
4012
|
+
const isTech = Spacestationtechnology.some(
|
|
4013
|
+
(t) => t.techname === target || t.techname == target
|
|
4014
|
+
);
|
|
4015
|
+
const isWeapon = Object.keys(weaponConfig).includes(target);
|
|
4016
|
+
if (isTech) {
|
|
4017
|
+
return handleTechUpgrade(handle, target);
|
|
4018
|
+
} else if (isWeapon) {
|
|
4019
|
+
return handleWeaponUpgrade(handle, target);
|
|
3782
4020
|
}
|
|
3783
|
-
return
|
|
3784
|
-
当前等级:${newLevel},伤害:${baseDamage},拥有改装槽:${slots}个。`;
|
|
4021
|
+
return `❌ 未找到 "${target}" 对应的武器或科技`;
|
|
3785
4022
|
});
|
|
3786
4023
|
ctx.command("ggcevo/改装 <weapon> [mod]", "安装武器模块").action(async ({ session }, weapon, mod) => {
|
|
3787
4024
|
const isValidWeapon = weapon && weaponConfig[weapon]?.id !== void 0;
|
|
@@ -4066,6 +4303,57 @@ ${effectMessage.join("\n")}`
|
|
|
4066
4303
|
await ctx.broadcast(groupId, finalBroadcast);
|
|
4067
4304
|
}
|
|
4068
4305
|
});
|
|
4306
|
+
ctx.command("ggcevo/攻击假人").usage("测试当前装备武器的伤害,可添加标签和被动\n用法:攻击假人 [--标签 标签1 标签2] [--被动 被动1 被动2]").option("tags", "-t <tags:string> 添加BOSS标签(逗号分隔)").option("passives", "-p <passives:string> 添加BOSS被动(逗号分隔)").action(async (argv) => {
|
|
4307
|
+
const session = argv.session;
|
|
4308
|
+
const { options } = argv;
|
|
4309
|
+
const parseList = /* @__PURE__ */ __name((str) => str ? str.split(",").map((s) => s.trim()).filter(Boolean) : [], "parseList");
|
|
4310
|
+
const tags = parseList(options.tags);
|
|
4311
|
+
const passives = parseList(options.passives);
|
|
4312
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4313
|
+
if (!profile) return "您暂未绑定句柄。";
|
|
4314
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4315
|
+
const existingEntries = await ctx.database.get("ggcevo_blacklist", { handle });
|
|
4316
|
+
if (existingEntries.length > 0) return "❌ 拒绝访问,您已被列入黑名单。";
|
|
4317
|
+
const [equippedWeapon] = await ctx.database.get("ggcevo_equipment", {
|
|
4318
|
+
handle,
|
|
4319
|
+
equipped: true
|
|
4320
|
+
});
|
|
4321
|
+
if (!equippedWeapon) return '请先输入"装备 武器名称"后再测试。';
|
|
4322
|
+
const dummyBoss = {
|
|
4323
|
+
name: "测试假人",
|
|
4324
|
+
HP: Infinity,
|
|
4325
|
+
type: "主宰",
|
|
4326
|
+
groupId: 0,
|
|
4327
|
+
skills: passives || [],
|
|
4328
|
+
// 从选项获取被动
|
|
4329
|
+
tags: tags || []
|
|
4330
|
+
// 从选项获取标签
|
|
4331
|
+
};
|
|
4332
|
+
const { damage, hasCrit, effectMessage } = await calculateTotalDamage(
|
|
4333
|
+
ctx,
|
|
4334
|
+
session,
|
|
4335
|
+
equippedWeapon,
|
|
4336
|
+
dummyBoss,
|
|
4337
|
+
{
|
|
4338
|
+
isTest: true,
|
|
4339
|
+
// 标记为测试模式
|
|
4340
|
+
customTags: tags,
|
|
4341
|
+
customPassives: passives
|
|
4342
|
+
}
|
|
4343
|
+
);
|
|
4344
|
+
const weaponConfigEntry = Object.entries(weaponConfig).find(([_, c]) => c.id === equippedWeapon.weaponId);
|
|
4345
|
+
const [weaponName] = weaponConfigEntry;
|
|
4346
|
+
return [
|
|
4347
|
+
`🎯 测试攻击 ${dummyBoss.name}`,
|
|
4348
|
+
`💥 使用武器:${weaponName}`,
|
|
4349
|
+
options.tags?.length && `🏷️ 模拟标签:${tags.join(", ")}`,
|
|
4350
|
+
options.passives?.length && `🛡️ 模拟被动:${passives.join(", ")}`,
|
|
4351
|
+
`📊 理论伤害值:${damage}`,
|
|
4352
|
+
hasCrit ? "✨ 触发暴击" : "",
|
|
4353
|
+
...effectMessage,
|
|
4354
|
+
"⚠️ 注意:假人默认无属性,标签和被动需手动添加"
|
|
4355
|
+
].filter((line) => line).join("\n");
|
|
4356
|
+
});
|
|
4069
4357
|
ctx.command("ggcevo/伤害榜 [page]", "查看当前主宰伤害排名").usage("输入 伤害榜 [页码] 查看对应页的排行榜,每页10条").action(async (_, page) => {
|
|
4070
4358
|
const pageNum = parseInt(page) || 1;
|
|
4071
4359
|
if (pageNum < 1) return "请输入有效的页码。";
|
|
@@ -4151,7 +4439,7 @@ ${effectMessage.join("\n")}`
|
|
|
4151
4439
|
name: minion.name,
|
|
4152
4440
|
type: "子代",
|
|
4153
4441
|
HP: minion.maxHP,
|
|
4154
|
-
tags:
|
|
4442
|
+
tags: minion.tags,
|
|
4155
4443
|
skills: [...minion.passive],
|
|
4156
4444
|
groupId: groupid,
|
|
4157
4445
|
isActive: true,
|
|
@@ -4489,7 +4777,6 @@ ${effectMessage.join("\n")}`
|
|
|
4489
4777
|
`🗓️ 就职时间:${formattedDate}`
|
|
4490
4778
|
];
|
|
4491
4779
|
if (careerData.group === "辛迪加海盗") {
|
|
4492
|
-
infoCard.push(`🔴 持有红晶:${careerData.redcrystal || 0} 个`);
|
|
4493
4780
|
infoCard.push("💡 提示:红晶可通过主动PK获得(无论胜负)");
|
|
4494
4781
|
} else {
|
|
4495
4782
|
infoCard.push("💡 提示:使用「转职」命令可变更职业");
|
|
@@ -4505,11 +4792,18 @@ ${effectMessage.join("\n")}`
|
|
|
4505
4792
|
}
|
|
4506
4793
|
});
|
|
4507
4794
|
ctx.command("ggcevo/黑市 [type]", "辛迪加海盗专属黑市").usage("输入“黑市”查看类型,或“黑市 类型”查看详细").action(async ({ session }, type) => {
|
|
4795
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4796
|
+
if (!profile) return "⚠️ 需要先绑定游戏句柄";
|
|
4797
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
4798
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
4799
|
+
if (!careerData || careerData.group !== "辛迪加海盗") {
|
|
4800
|
+
return "🚫 该功能需要【辛迪加海盗】阵营权限";
|
|
4801
|
+
}
|
|
4508
4802
|
const typeStats = {};
|
|
4509
|
-
Object.values(weaponConfig).forEach((weapon) => {
|
|
4803
|
+
Object.values(weaponConfig).filter((config2) => config2.redCrystalCost > 0).forEach((weapon) => {
|
|
4510
4804
|
typeStats[weapon.type] = (typeStats[weapon.type] || 0) + 1;
|
|
4511
4805
|
});
|
|
4512
|
-
Object.values(SyndicatedItems).forEach((item) => {
|
|
4806
|
+
Object.values(SyndicatedItems).filter((item) => item.redCrystalCost > 0).forEach((item) => {
|
|
4513
4807
|
typeStats[item.type] = (typeStats[item.type] || 0) + 1;
|
|
4514
4808
|
});
|
|
4515
4809
|
if (!type) {
|
|
@@ -4524,12 +4818,15 @@ ${effectMessage.join("\n")}`
|
|
|
4524
4818
|
const normalizedType = Object.keys(typeStats).find((t) => t === type);
|
|
4525
4819
|
if (!normalizedType) return `无效类型,可用:${Object.keys(typeStats).join("、")}`;
|
|
4526
4820
|
const items = [
|
|
4527
|
-
...Object.entries(weaponConfig).filter(
|
|
4821
|
+
...Object.entries(weaponConfig).filter(
|
|
4822
|
+
([_, config2]) => config2.type === normalizedType && config2.redCrystalCost > 0
|
|
4823
|
+
).map(([name2, config2]) => {
|
|
4528
4824
|
const infoBlocks = [
|
|
4529
4825
|
`【${name2}】`,
|
|
4530
4826
|
`类型:${config2.type}`,
|
|
4531
4827
|
...config2.damage ? [`基础伤害:${config2.damage}`] : [],
|
|
4532
4828
|
`订购价:${config2.redCrystalCost}红晶`
|
|
4829
|
+
// 只显示红晶价格
|
|
4533
4830
|
];
|
|
4534
4831
|
if (Object.keys(config2.tagEffects).length > 0) {
|
|
4535
4832
|
const tagEffectsDesc = Object.entries(config2.tagEffects).map(([tag, mul]) => `▸ 对${tag}目标造成${(mul * 100).toFixed(0)}%伤害`).join("\n");
|
|
@@ -4541,13 +4838,16 @@ ${effectMessage.join("\n")}`
|
|
|
4541
4838
|
);
|
|
4542
4839
|
return infoBlocks.join("\n");
|
|
4543
4840
|
}),
|
|
4544
|
-
...Object.entries(SyndicatedItems).filter(
|
|
4841
|
+
...Object.entries(SyndicatedItems).filter(
|
|
4842
|
+
([_, item]) => item.type === normalizedType && item.redCrystalCost > 0
|
|
4843
|
+
).map(([name2, item]) => {
|
|
4545
4844
|
const infoBlocks = [
|
|
4546
4845
|
`【${name2}】`,
|
|
4547
4846
|
`类型:${item.type}`,
|
|
4548
4847
|
`订购价:${item.redCrystalCost}红晶`,
|
|
4848
|
+
// 只显示红晶价格
|
|
4549
4849
|
`效果:${item.effects}`,
|
|
4550
|
-
item.description
|
|
4850
|
+
`描述:${item.description}`,
|
|
4551
4851
|
"──────────────"
|
|
4552
4852
|
];
|
|
4553
4853
|
return infoBlocks.join("\n");
|
|
@@ -4688,7 +4988,7 @@ ${effectMessage.join("\n")}`
|
|
|
4688
4988
|
}
|
|
4689
4989
|
return message.join("\n");
|
|
4690
4990
|
});
|
|
4691
|
-
ctx.command("ggcevo/使用 [itemName]").action(async (argv, itemName) => {
|
|
4991
|
+
ctx.command("ggcevo/使用 [itemName] [target]").action(async (argv, itemName, target) => {
|
|
4692
4992
|
const session = argv.session;
|
|
4693
4993
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
4694
4994
|
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
@@ -4710,24 +5010,18 @@ ${effectMessage.join("\n")}`
|
|
|
4710
5010
|
([_, item]) => item.id === targetItem.itemId
|
|
4711
5011
|
);
|
|
4712
5012
|
const [itemNameConfirmed, itemConfig2] = itemEntry;
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
name: "空间站哨枪塔",
|
|
4716
|
-
isActive: true
|
|
4717
|
-
});
|
|
4718
|
-
if (!activeSentry.length) return "⚠️ 目标「空间站哨枪塔」未激活";
|
|
4719
|
-
}
|
|
5013
|
+
const effectResult = await applyItemEffect(session, handle, itemConfig2, target);
|
|
5014
|
+
if (!effectResult.success) return effectResult.message;
|
|
4720
5015
|
const newQuantity = targetItem.quantity - 1;
|
|
4721
5016
|
await ctx.database.set(
|
|
4722
5017
|
"ggcevo_warehouse",
|
|
4723
5018
|
{ handle, itemId: targetItem.itemId },
|
|
4724
5019
|
{ quantity: newQuantity }
|
|
4725
5020
|
);
|
|
4726
|
-
const effectResult = await applyItemEffect(session, handle, itemConfig2);
|
|
4727
5021
|
return [
|
|
4728
5022
|
`✅ 成功使用 ${itemNameConfirmed}`,
|
|
4729
5023
|
`├ 剩余数量:${newQuantity}`,
|
|
4730
|
-
`└ 效果触发:${effectResult}`,
|
|
5024
|
+
`└ 效果触发:${effectResult.message}`,
|
|
4731
5025
|
"─".repeat(25)
|
|
4732
5026
|
].join("\n");
|
|
4733
5027
|
} catch (error) {
|
|
@@ -4735,6 +5029,77 @@ ${effectMessage.join("\n")}`
|
|
|
4735
5029
|
return "⚠️ 物品使用失败,请联系管理员";
|
|
4736
5030
|
}
|
|
4737
5031
|
});
|
|
5032
|
+
ctx.command("ggcevo/科技信息", "查看空间站科技配置").action(async ({ session }) => {
|
|
5033
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5034
|
+
if (!profile) return "❌ 您暂未绑定句柄。";
|
|
5035
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5036
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5037
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
5038
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
5039
|
+
}
|
|
5040
|
+
const techEntries = await ctx.database.get("ggcevo_tech", { handle });
|
|
5041
|
+
const techInfo = Spacestationtechnology.map((tech) => {
|
|
5042
|
+
const entry = techEntries.find((e) => e.techId === tech.techId);
|
|
5043
|
+
const currentLevel = entry?.level || 0;
|
|
5044
|
+
const levelData = tech.levels.find((l) => l.level === currentLevel);
|
|
5045
|
+
let description = "尚未解锁";
|
|
5046
|
+
let careerBonus = "无";
|
|
5047
|
+
if (levelData) {
|
|
5048
|
+
description = levelData.description;
|
|
5049
|
+
careerBonus = levelData.careerBonus;
|
|
5050
|
+
}
|
|
5051
|
+
return `🛠️ ${tech.techname} [${currentLevel}/${tech.maxLevel}]
|
|
5052
|
+
📌 效果:${description}
|
|
5053
|
+
🎖️ ${careerBonus}`;
|
|
5054
|
+
}).join("\n\n");
|
|
5055
|
+
return `🚀 空间站科技配置信息:
|
|
5056
|
+
|
|
5057
|
+
${techInfo}`;
|
|
5058
|
+
});
|
|
5059
|
+
ctx.command("ggcevo/科技 [techName]", "查看空间站科技信息").usage("输入“科技”查看列表,或“科技 科技名称”查看详细信息").action(async ({ session }, techName) => {
|
|
5060
|
+
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
5061
|
+
if (!profile) return "🔒 需要先绑定游戏句柄";
|
|
5062
|
+
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
5063
|
+
const [careerData] = await ctx.database.get("ggcevo_careers", { handle });
|
|
5064
|
+
if (!careerData || careerData.group !== "人类联盟") {
|
|
5065
|
+
return "🚫 该功能需要【人类联盟】阵营权限";
|
|
5066
|
+
}
|
|
5067
|
+
const romanNumerals = { 1: "I", 2: "II", 3: "III", 4: "IV", 5: "V" };
|
|
5068
|
+
if (!techName) {
|
|
5069
|
+
const techList = Spacestationtechnology.map(
|
|
5070
|
+
(tech2) => `▸ ${tech2.techname} (最大等级 ${romanNumerals[tech2.maxLevel]})`
|
|
5071
|
+
);
|
|
5072
|
+
return [
|
|
5073
|
+
"🛰️ 空间站科技系统 🛰️",
|
|
5074
|
+
'使用 "科技 科技名称" 查看详细信息',
|
|
5075
|
+
"====================",
|
|
5076
|
+
...techList,
|
|
5077
|
+
"===================="
|
|
5078
|
+
].join("\n");
|
|
5079
|
+
}
|
|
5080
|
+
const tech = Spacestationtechnology.find(
|
|
5081
|
+
(t) => t.techname === techName
|
|
5082
|
+
);
|
|
5083
|
+
if (!tech) return `❌ 无效科技名称,可用科技:
|
|
5084
|
+
${Spacestationtechnology.map((t) => t.techname).join("、")}`;
|
|
5085
|
+
const techDetails = tech.levels.map((level) => {
|
|
5086
|
+
return [
|
|
5087
|
+
`✦ 等级 ${romanNumerals[level.level]}`,
|
|
5088
|
+
`▸ 升级花费:${level.cost}金币`,
|
|
5089
|
+
`▸ 基础效果:${level.description}`,
|
|
5090
|
+
`💼 ${level.careerBonus}`,
|
|
5091
|
+
"------------------"
|
|
5092
|
+
].join("\n");
|
|
5093
|
+
});
|
|
5094
|
+
return [
|
|
5095
|
+
`🛠️ ${tech.techname} 科技详情 🛠️`,
|
|
5096
|
+
`最大可升级等级:${romanNumerals[tech.maxLevel]}`,
|
|
5097
|
+
'使用 "升级 科技名称" 进行升级',
|
|
5098
|
+
"====================",
|
|
5099
|
+
...techDetails,
|
|
5100
|
+
"===================="
|
|
5101
|
+
].join("\n");
|
|
5102
|
+
});
|
|
4738
5103
|
}
|
|
4739
5104
|
__name(apply, "apply");
|
|
4740
5105
|
function simpleDraw() {
|