koishi-plugin-xxck-1 0.3.5 → 0.3.7
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 +7 -0
- package/lib/index.js +176 -13
- package/lib/locales/zh-CN/index.d.ts +8 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface PluginConfig {
|
|
|
11
11
|
eventExchangePrice7: number;
|
|
12
12
|
collectionPart1Pattern: string;
|
|
13
13
|
collectionPart2Pattern: string;
|
|
14
|
+
disturbExchangePrice: number;
|
|
14
15
|
normalStar7Threshold: number;
|
|
15
16
|
normalStar6Threshold: number;
|
|
16
17
|
normalStar6Prob: number;
|
|
@@ -27,6 +28,7 @@ export declare const Config: Schema<Schemastery.ObjectS<{
|
|
|
27
28
|
eventExchangePrice7: Schema<number, number>;
|
|
28
29
|
collectionPart1Pattern: Schema<string, string>;
|
|
29
30
|
collectionPart2Pattern: Schema<string, string>;
|
|
31
|
+
disturbExchangePrice: Schema<number, number>;
|
|
30
32
|
normalStar7Threshold: Schema<number, number>;
|
|
31
33
|
normalStar6Threshold: Schema<number, number>;
|
|
32
34
|
normalStar6Prob: Schema<number, number>;
|
|
@@ -42,6 +44,7 @@ export declare const Config: Schema<Schemastery.ObjectS<{
|
|
|
42
44
|
eventExchangePrice7: Schema<number, number>;
|
|
43
45
|
collectionPart1Pattern: Schema<string, string>;
|
|
44
46
|
collectionPart2Pattern: Schema<string, string>;
|
|
47
|
+
disturbExchangePrice: Schema<number, number>;
|
|
45
48
|
normalStar7Threshold: Schema<number, number>;
|
|
46
49
|
normalStar6Threshold: Schema<number, number>;
|
|
47
50
|
normalStar6Prob: Schema<number, number>;
|
|
@@ -144,6 +147,10 @@ declare module 'koishi' {
|
|
|
144
147
|
got6: boolean;
|
|
145
148
|
got7: boolean;
|
|
146
149
|
};
|
|
150
|
+
gacha_user_disturb_draw: {
|
|
151
|
+
qq: string;
|
|
152
|
+
draw_count: number;
|
|
153
|
+
};
|
|
147
154
|
gacha_battle_user: {
|
|
148
155
|
qq: string;
|
|
149
156
|
win: number;
|
package/lib/index.js
CHANGED
|
@@ -40,7 +40,7 @@ var zh_CN_default = {
|
|
|
40
40
|
"command.wwc.help.sign": "签到:每日领取抽数 | 指令:WWC签到 | 说明:每日1次,获得40抽",
|
|
41
41
|
"command.wwc.help.draw": "抽卡:普通抽卡 | 指令:WWC抽卡 [次数] | 说明:1-20连,消耗普通抽数,默认1连",
|
|
42
42
|
"command.wwc.help.warehouse": "仓库:查看已拥有卡片 | 指令:WWC仓库 | 说明:显示等级/星级/限定标记,按星级排序",
|
|
43
|
-
"command.wwc.help.shop": "店铺:查看今日可升格卡片 | 指令:WWC店铺 | 说明:每日随机刷新
|
|
43
|
+
"command.wwc.help.shop": "店铺:查看今日可升格卡片 | 指令:WWC店铺 | 说明:每日随机刷新4个7星、6个6星、10个5星(均来自普通卡池),全服限购5次",
|
|
44
44
|
"command.wwc.help.upgrade": "升格:兑换店铺卡片 | 指令:WWC升格 [卡片编号...] | 说明:消耗热带扰动,重复卡片自动升级",
|
|
45
45
|
"command.wwc.help.exchange": "兑换:水汽换普通抽数 | 指令:WWC兑换 [次数] | 说明:100水汽=1抽,每日上限80抽,单次1-40",
|
|
46
46
|
"command.wwc.help.collection": "收藏:查看卡片收藏进度 | 指令:WWC收藏(全部分类);WWC收藏1 / WWC收藏2 / WWC收藏3 为拆分版(分类正则可在插件配置项 collectionPart1Pattern / collectionPart2Pattern 中定义,收藏3 = 两者都不匹配的类别)| 说明:含普通+限定卡",
|
|
@@ -48,6 +48,8 @@ var zh_CN_default = {
|
|
|
48
48
|
"command.wwc.help.eventStatus": "限时状态:查看开放的限时卡池 | 指令:WWC限时状态 | 说明:显示期数/名称/星级/开放时间",
|
|
49
49
|
"command.wwc.help.eventDraw": "限时抽卡:参与限时卡池 | 指令:WWC限时抽卡 [期数] [次数] | 说明:1-20连,消耗限时抽数,无期限数匹配唯一开放池",
|
|
50
50
|
"command.wwc.help.eventExchange": "限时兑换:水汽换限时抽数 | 指令:WWC限时兑换 [期数] [次数] | 说明:6星300水汽/抽,7星450水汽/抽,单次1-40",
|
|
51
|
+
"command.wwc.help.disturbDraw": "扰动抽卡:使用扰动抽数抽卡 | 指令:WWC扰动抽卡 [次数] | 说明:普通卡池5/6/7星,7星10%、6星36%、5星54%,单次1-20连",
|
|
52
|
+
"command.wwc.help.disturbExchange": "扰动兑换:热带扰动换扰动抽数 | 指令:WWC扰动兑换 [次数] | 说明:每抽消耗扰动由配置项决定(默认100),单次1-40",
|
|
51
53
|
"command.wwc.help.tip": "💡 提示:所有指令前缀为「WWC」,区分大小写;抽卡/兑换次数超出限制会自动兜底为1次",
|
|
52
54
|
// ==============================================
|
|
53
55
|
// 2. 功能操作成功提示
|
|
@@ -64,6 +66,8 @@ var zh_CN_default = {
|
|
|
64
66
|
"tip.switch.groupClose": "❌ 本群WWC抽卡功能已关闭!群成员无法使用任何指令",
|
|
65
67
|
"tip.eventAdd.success": "✅ 限时卡池创建成功:{code} | 请检查时间戳是否正确",
|
|
66
68
|
"tip.eventExchange.success": "✅ 限时兑换成功\n卡池:{code} | 数量:{count}抽 | 消耗:{cost}水汽",
|
|
69
|
+
"tip.disturbExchange.success": "✅ 扰动兑换成功\n数量:{count}抽 | 消耗:{cost}热带扰动 | 当前扰动抽数:{left}抽",
|
|
70
|
+
"tip.disturbDraw.title": "🎲 [{name}] 扰动抽卡完成(剩余扰动抽数:{left}抽)!获得以下卡片:",
|
|
67
71
|
"tip.eventStatus.info": "📅 限时卡池【{code}】\n卡片:{cardName}({star}星)\n类型:{type}\n开放时间:{start} ~ {end}",
|
|
68
72
|
"tip.upgrade.success": "✅ 升格成功!恭喜您获得了以下卡片:\n",
|
|
69
73
|
"tip.upgrade.cost": "💸 消耗扰动:-{total_cost}",
|
|
@@ -76,6 +80,8 @@ var zh_CN_default = {
|
|
|
76
80
|
"tip.draw.upgrade": "✅ 原有卡片升级成功\n",
|
|
77
81
|
"tip.draw.vapor": "💧 水汽 +{vapor}\n",
|
|
78
82
|
"tip.draw.disturb": "🌪️ 热带扰动 +{disturbanceTotal}",
|
|
83
|
+
"tip.draw.left": "🔢 剩余普通抽数:{left}抽",
|
|
84
|
+
"tip.eventDraw.left": "🔢 剩余{star}星限时抽数:{left}抽",
|
|
79
85
|
"tip.eventDraw.pityReset": "✨ 已获得当期限时{star}星卡,保底进度重置;",
|
|
80
86
|
"tip.eventDraw.pityProgress": "📊 限时{star}星保底进度:{current}/{threshold}抽(再抽{left}抽必出);",
|
|
81
87
|
// ==============================================
|
|
@@ -111,6 +117,8 @@ var zh_CN_default = {
|
|
|
111
117
|
"error.eventDraw.count.notEnough": "❌ {star}星限时抽数不足:\n当前{have}抽/需要{need}抽\n可使用WWC限时兑换获取",
|
|
112
118
|
"error.eventDraw.param.invalid": "❌ 抽卡参数无效,请传入期数和次数",
|
|
113
119
|
"error.eventExchange.pool.none": "❌ 该期数限时卡池未开放或不存在!\n请使用WWC限时状态查看",
|
|
120
|
+
"error.disturbExchange.disturb.notEnough": "❌ 热带扰动不足!\n本次兑换需要:{need}扰动 | 当前拥有:{have}扰动",
|
|
121
|
+
"error.disturbDraw.count.notEnough": "❌ 扰动抽数不足!\n当前剩余:{have} 次 | 需要:{need} 次(可使用 WWC扰动兑换 兑换)",
|
|
114
122
|
"error.switch.private": "❌ 私信场景无需设置群开关!该指令仅可在群聊中使用",
|
|
115
123
|
"error.switch.fail": "❌ 开关操作失败!{msg}",
|
|
116
124
|
"error.shop.no7starCard": "❌ 店铺生成失败!普通卡池中无7星卡片,请联系主人录入",
|
|
@@ -134,7 +142,7 @@ var zh_CN_default = {
|
|
|
134
142
|
"image.warehouse.empty": "你的仓库暂无任何卡片,快去抽卡吧!",
|
|
135
143
|
"image.shop.title": "WWC每日商店({date})",
|
|
136
144
|
"image.shop.userInfo": "玩家:{name}",
|
|
137
|
-
"image.shop.asset": "热带扰动: {disturb} | 水汽:{vapor}",
|
|
145
|
+
"image.shop.asset": "热带扰动: {disturb} | 水汽:{vapor} | 剩余抽数:{draw}",
|
|
138
146
|
"image.shop.exchangeCount": "今日普通兑换:{used}/{limit}抽(单次最多40)",
|
|
139
147
|
"image.shop.header.card": "卡片信息",
|
|
140
148
|
"image.shop.header.price": "升格价格",
|
|
@@ -180,6 +188,7 @@ var Config = import_koishi.Schema.object({
|
|
|
180
188
|
eventExchangePrice7: import_koishi.Schema.number().description("限时卡池7星兑换每抽消耗的水汽量(默认450)").default(450).min(1).max(1e4),
|
|
181
189
|
collectionPart1Pattern: import_koishi.Schema.string().description('WWC收藏1的分类正则:类别名匹配此正则的归入收藏图1(默认匹配"纯数字且≥2000")').default("^([2-9]\\d{3}|\\d{5,})$").role("textarea"),
|
|
182
190
|
collectionPart2Pattern: import_koishi.Schema.string().description('WWC收藏2的分类正则:类别名匹配此正则的归入收藏图2(默认匹配"纯数字且<2000");两个正则都不匹配的类别归入WWC收藏3').default("^(\\d{1,3}|1\\d{3})$").role("textarea"),
|
|
191
|
+
disturbExchangePrice: import_koishi.Schema.number().description("扰动兑换:每抽扰动抽数消耗的热带扰动量(默认100)").default(100).min(1).max(1e5),
|
|
183
192
|
normalStar7Threshold: import_koishi.Schema.number().description("普通卡池7星保底抽数(默认1500)").default(1500).min(1).max(1e4),
|
|
184
193
|
normalStar6Threshold: import_koishi.Schema.number().description("普通卡池6星保底抽数(默认300)").default(300).min(1).max(1e4),
|
|
185
194
|
normalStar6Prob: import_koishi.Schema.number().description("普通卡池6星保底抽出6星概率百分比(减去为抽出7星概率)").default(90).min(0).max(100),
|
|
@@ -335,15 +344,19 @@ async function _warehouse_draw_image(ctx, user_cards, show_name, titleText, empt
|
|
|
335
344
|
}
|
|
336
345
|
}
|
|
337
346
|
__name(_warehouse_draw_image, "_warehouse_draw_image");
|
|
338
|
-
async function _shop_draw_image(ctx, session, userName, date, disturbance, vapor, usedExchange, limitExchange, shopCards) {
|
|
347
|
+
async function _shop_draw_image(ctx, session, userName, date, disturbance, vapor, drawLeft, usedExchange, limitExchange, shopCards) {
|
|
339
348
|
ctx.logger.info("开始绘制店铺图片(最终稳定版)");
|
|
340
349
|
try {
|
|
341
350
|
if (!ctx.canvas) return null;
|
|
342
351
|
const BASE_X = 40;
|
|
343
352
|
const BASE_Y = 30;
|
|
344
353
|
const CANVAS_WIDTH = 900;
|
|
345
|
-
const CANVAS_HEIGHT = 1100;
|
|
346
354
|
const CARD_ITEM_HEIGHT = 85;
|
|
355
|
+
const FIRST_CARD_Y = BASE_Y + 235;
|
|
356
|
+
const CANVAS_HEIGHT = Math.max(
|
|
357
|
+
1100,
|
|
358
|
+
FIRST_CARD_Y + Math.max(0, (shopCards?.length ?? 0) - 1) * CARD_ITEM_HEIGHT + 70
|
|
359
|
+
);
|
|
347
360
|
const FONT_FAMILY = "Microsoft YaHei, SimHei, 黑体, 宋体, sans-serif";
|
|
348
361
|
const canvas = ctx.canvas.createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT);
|
|
349
362
|
const ctx2d = canvas.getContext("2d");
|
|
@@ -354,6 +367,7 @@ async function _shop_draw_image(ctx, session, userName, date, disturbance, vapor
|
|
|
354
367
|
ctx2d.textAlign = "left";
|
|
355
368
|
const distStr = String(disturbance ?? 0);
|
|
356
369
|
const vaporStr = String(vapor ?? 0);
|
|
370
|
+
const drawStr = String(drawLeft ?? 0);
|
|
357
371
|
ctx2d.save();
|
|
358
372
|
ctx2d.textAlign = "center";
|
|
359
373
|
ctx2d.fillStyle = "#E53E3E";
|
|
@@ -363,7 +377,7 @@ async function _shop_draw_image(ctx, session, userName, date, disturbance, vapor
|
|
|
363
377
|
ctx2d.fillStyle = "#222";
|
|
364
378
|
ctx2d.font = `20px ${FONT_FAMILY}`;
|
|
365
379
|
ctx2d.fillText(`玩家:${userName}`, BASE_X, BASE_Y + 80);
|
|
366
|
-
ctx2d.fillText(`热带扰动:${distStr}|水汽:${vaporStr}`, BASE_X, BASE_Y + 120);
|
|
380
|
+
ctx2d.fillText(`热带扰动:${distStr}|水汽:${vaporStr}|剩余抽数:${drawStr}`, BASE_X, BASE_Y + 120);
|
|
367
381
|
const headerY = BASE_Y + 200;
|
|
368
382
|
ctx2d.save();
|
|
369
383
|
ctx2d.fillStyle = "#000";
|
|
@@ -955,6 +969,7 @@ async function _do_draw(ctx, session, draw_times, star7Threshold, star6Threshold
|
|
|
955
969
|
if (isUpgrade) info += session.text("tip.draw.upgrade");
|
|
956
970
|
info += session.text("tip.draw.vapor", { vapor: waterVaporTotal });
|
|
957
971
|
info += session.text("tip.draw.disturb", { disturbanceTotal });
|
|
972
|
+
info += "\n" + session.text("tip.draw.left", { left: haveDraw - draw_times });
|
|
958
973
|
if (info) msg += "\n" + info.replace(/;$/, "");
|
|
959
974
|
await session.send(build_msg(session, msg));
|
|
960
975
|
}
|
|
@@ -1287,20 +1302,24 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
|
|
|
1287
1302
|
const today = `${todayDate.getFullYear()}${String(todayDate.getMonth() + 1).padStart(2, "0")}${String(todayDate.getDate()).padStart(2, "0")}`;
|
|
1288
1303
|
let todayShop = await ctx.database.get("gacha_shop_daily", { shop_date: today });
|
|
1289
1304
|
if (todayShop.length === 0) {
|
|
1290
|
-
const [sevenStarCards, sixStarCards] = await Promise.all([
|
|
1305
|
+
const [sevenStarCards, sixStarCards, fiveStarCards] = await Promise.all([
|
|
1291
1306
|
ctx.database.get("gacha_card_pool", { card_star: 7 }),
|
|
1292
|
-
ctx.database.get("gacha_card_pool", { card_star: 6 })
|
|
1307
|
+
ctx.database.get("gacha_card_pool", { card_star: 6 }),
|
|
1308
|
+
ctx.database.get("gacha_card_pool", { card_star: 5 })
|
|
1293
1309
|
]);
|
|
1294
|
-
if (sevenStarCards.length < 4 || sixStarCards.length < 6) {
|
|
1310
|
+
if (sevenStarCards.length < 4 || sixStarCards.length < 6 || fiveStarCards.length < 10) {
|
|
1295
1311
|
return await session.send(import_koishi.h.text(session.text("error.shop.cardNotEnough")));
|
|
1296
1312
|
}
|
|
1297
1313
|
const selected7 = sevenStarCards.sort(() => Math.random() - 0.5).slice(0, 4);
|
|
1298
1314
|
const selected6 = sixStarCards.sort(() => Math.random() - 0.5).slice(0, 6);
|
|
1299
|
-
const
|
|
1315
|
+
const selected5 = fiveStarCards.sort(() => Math.random() - 0.5).slice(0, 10);
|
|
1316
|
+
const allCards = [...selected7, ...selected6, ...selected5];
|
|
1317
|
+
const SHOP_PRICE_BASE = { 7: 800, 6: 200, 5: 20 };
|
|
1318
|
+
const SHOP_PRICE_RANGE = { 7: 80, 6: 30, 5: 0 };
|
|
1300
1319
|
for (const card of allCards) {
|
|
1301
|
-
const basePrice = card.card_star
|
|
1302
|
-
const range = card.card_star
|
|
1303
|
-
const randomPrice = basePrice + Math.floor(Math.random() * (range * 2 + 1)) - range;
|
|
1320
|
+
const basePrice = SHOP_PRICE_BASE[card.card_star] ?? 10;
|
|
1321
|
+
const range = SHOP_PRICE_RANGE[card.card_star] ?? 0;
|
|
1322
|
+
const randomPrice = range > 0 ? basePrice + Math.floor(Math.random() * (range * 2 + 1)) - range : basePrice;
|
|
1304
1323
|
const nextId = await getNextId(ctx, "gacha_shop_daily");
|
|
1305
1324
|
await ctx.database.create("gacha_shop_daily", {
|
|
1306
1325
|
id: nextId,
|
|
@@ -1342,9 +1361,11 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
|
|
|
1342
1361
|
leftLimit: limitMap.get(item.card_id)
|
|
1343
1362
|
};
|
|
1344
1363
|
});
|
|
1364
|
+
shopCardList.sort((a, b) => b.star - a.star || String(a.id).localeCompare(String(b.id)));
|
|
1345
1365
|
const userAsset = await ctx.database.get("gacha_user_draw_count", { qq });
|
|
1346
1366
|
const dist = userAsset[0]?.tropical_disturbance ?? 0;
|
|
1347
1367
|
const vapor = userAsset[0]?.water_vapor ?? 0;
|
|
1368
|
+
const drawLeft = userAsset[0]?.draw_count ?? 0;
|
|
1348
1369
|
const img = await _shop_draw_image(
|
|
1349
1370
|
ctx,
|
|
1350
1371
|
session,
|
|
@@ -1352,6 +1373,7 @@ async function _do_shop(ctx, session, signResetHour, signResetMinute) {
|
|
|
1352
1373
|
today,
|
|
1353
1374
|
dist,
|
|
1354
1375
|
vapor,
|
|
1376
|
+
drawLeft,
|
|
1355
1377
|
0,
|
|
1356
1378
|
0,
|
|
1357
1379
|
shopCardList
|
|
@@ -1878,6 +1900,7 @@ async function _do_event_draw(ctx, session, data, event6Threshold, event7Thresho
|
|
|
1878
1900
|
} else {
|
|
1879
1901
|
info += session.text("tip.eventDraw.pityReset", { star: limitStar });
|
|
1880
1902
|
}
|
|
1903
|
+
info += "\n" + session.text("tip.eventDraw.left", { star: limitStar, left: have - count });
|
|
1881
1904
|
if (info) msg += "\n" + info.replace(/;$/, "");
|
|
1882
1905
|
await session.send(build_msg(session, msg));
|
|
1883
1906
|
if (true) {
|
|
@@ -1894,6 +1917,128 @@ async function _do_event_draw(ctx, session, data, event6Threshold, event7Thresho
|
|
|
1894
1917
|
}
|
|
1895
1918
|
}
|
|
1896
1919
|
__name(_do_event_draw, "_do_event_draw");
|
|
1920
|
+
async function _do_disturb_exchange(ctx, session, cnt, price) {
|
|
1921
|
+
const qq = await getUnifiedQQ(ctx, session);
|
|
1922
|
+
const realCnt = Math.min(Math.max(cnt | 0, 1), 40);
|
|
1923
|
+
const user = await ctx.database.get("gacha_user", { qq });
|
|
1924
|
+
if (!user.length) return await session.send(build_msg(session, session.text("error.common.notRegister")));
|
|
1925
|
+
const total = price * realCnt;
|
|
1926
|
+
const asset = await ctx.database.get("gacha_user_draw_count", { qq });
|
|
1927
|
+
const disturb = asset[0]?.tropical_disturbance ?? 0;
|
|
1928
|
+
if (disturb < total) {
|
|
1929
|
+
ctx.logger.warn(`[扰动兑换] 玩家${qq}兑换失败:热带扰动不足(拥有${disturb},需${total})`);
|
|
1930
|
+
return await session.send(build_msg(session, session.text("error.disturbExchange.disturb.notEnough", { need: total, have: disturb })));
|
|
1931
|
+
}
|
|
1932
|
+
await ctx.database.upsert("gacha_user_draw_count", [{ qq, tropical_disturbance: disturb - total }]);
|
|
1933
|
+
const ud = await ctx.database.get("gacha_user_disturb_draw", { qq });
|
|
1934
|
+
const have = ud[0]?.draw_count ?? 0;
|
|
1935
|
+
await ctx.database.upsert("gacha_user_disturb_draw", [{ qq, draw_count: have + realCnt }]);
|
|
1936
|
+
ctx.logger.info(`[扰动兑换] 玩家${qq}兑换成功:获得${realCnt}抽,消耗扰动${total},扰动抽数${have}→${have + realCnt}`);
|
|
1937
|
+
await session.send(build_msg(
|
|
1938
|
+
session,
|
|
1939
|
+
session.text("tip.disturbExchange.success", { count: realCnt, cost: total, left: have + realCnt })
|
|
1940
|
+
));
|
|
1941
|
+
}
|
|
1942
|
+
__name(_do_disturb_exchange, "_do_disturb_exchange");
|
|
1943
|
+
async function _do_disturb_draw(ctx, session, count) {
|
|
1944
|
+
ctx.logger.info("执行扰动抽卡,次数:", count);
|
|
1945
|
+
const qq = await getUnifiedQQ(ctx, session);
|
|
1946
|
+
const user = await ctx.database.get("gacha_user", { qq });
|
|
1947
|
+
if (!user.length) return await session.send(build_msg(session, session.text("error.common.notRegister")));
|
|
1948
|
+
const showName = user[0].status === 1 ? user[0].nickname : qq;
|
|
1949
|
+
if (!Number.isInteger(count) || count < 1 || count > 20) {
|
|
1950
|
+
return await session.send(build_msg(session, session.text("error.draw.count.invalid")));
|
|
1951
|
+
}
|
|
1952
|
+
const ud = await ctx.database.get("gacha_user_disturb_draw", { qq });
|
|
1953
|
+
const have = ud[0]?.draw_count ?? 0;
|
|
1954
|
+
if (have < count) {
|
|
1955
|
+
return await session.send(build_msg(session, session.text("error.disturbDraw.count.notEnough", {
|
|
1956
|
+
need: count,
|
|
1957
|
+
have
|
|
1958
|
+
})));
|
|
1959
|
+
}
|
|
1960
|
+
const allCards = await ctx.database.get("gacha_card_pool", {});
|
|
1961
|
+
const starCardMap = { 5: [], 6: [], 7: [] };
|
|
1962
|
+
allCards.forEach((card) => {
|
|
1963
|
+
if (starCardMap[card.card_star]) starCardMap[card.card_star].push(card);
|
|
1964
|
+
});
|
|
1965
|
+
const DISTURB_STAR_PROB = { 7: 10, 6: 36, 5: 54 };
|
|
1966
|
+
const weightedPool = [];
|
|
1967
|
+
for (const [star, prob] of Object.entries(DISTURB_STAR_PROB)) {
|
|
1968
|
+
if (!starCardMap[+star]?.length) continue;
|
|
1969
|
+
for (let i = 0; i < prob; i++) weightedPool.push(+star);
|
|
1970
|
+
}
|
|
1971
|
+
if (!weightedPool.length) {
|
|
1972
|
+
return await session.send(build_msg(session, session.text("error.draw.poolEmpty")));
|
|
1973
|
+
}
|
|
1974
|
+
const STAR_TO_DISTURBANCE = { 0: 0, 1: 0, 2: 0, 3: 1, 4: 5, 5: 20, 6: 100, 7: 500 };
|
|
1975
|
+
const INIT_WATER_VAPOR = { 0: 50, 1: 100, 2: 150, 3: 200, 4: 500, 5: 1e3, 6: 2e3, 7: 5e3 };
|
|
1976
|
+
const UPGRADE_WATER_VAPOR = { 0: 25, 1: 50, 2: 75, 3: 100, 4: 200, 5: 500, 6: 1e3, 7: 2e3 };
|
|
1977
|
+
const drawResult = [];
|
|
1978
|
+
let disturbanceTotal = 0;
|
|
1979
|
+
let waterVaporTotal = 0;
|
|
1980
|
+
let isUpgrade = false;
|
|
1981
|
+
for (let i = 0; i < count; i++) {
|
|
1982
|
+
const selectedStar = weightedPool[Math.floor(Math.random() * weightedPool.length)];
|
|
1983
|
+
const cardList = starCardMap[selectedStar];
|
|
1984
|
+
const card = cardList[Math.floor(Math.random() * cardList.length)];
|
|
1985
|
+
drawResult.push({ star: selectedStar, cid: card.card_id, name: card.card_name });
|
|
1986
|
+
const userCard = await ctx.database.get("gacha_user_card", { qq, card_id: card.card_id });
|
|
1987
|
+
if (!userCard.length) {
|
|
1988
|
+
await ctx.database.upsert("gacha_user_card", [{
|
|
1989
|
+
qq,
|
|
1990
|
+
card_id: card.card_id,
|
|
1991
|
+
card_level: 0,
|
|
1992
|
+
obtain_at: Date.now()
|
|
1993
|
+
}]);
|
|
1994
|
+
waterVaporTotal += INIT_WATER_VAPOR[selectedStar];
|
|
1995
|
+
ctx.logger.info(`[扰动抽卡] 新增卡片:${card.card_id} ${card.card_name},等级0`);
|
|
1996
|
+
} else {
|
|
1997
|
+
const currentLevel = userCard[0].card_level;
|
|
1998
|
+
if (currentLevel < CARD_LEVEL_MAX) {
|
|
1999
|
+
await ctx.database.upsert("gacha_user_card", [{
|
|
2000
|
+
id: userCard[0].id,
|
|
2001
|
+
qq,
|
|
2002
|
+
card_id: card.card_id,
|
|
2003
|
+
card_level: currentLevel + 1,
|
|
2004
|
+
obtain_at: Date.now()
|
|
2005
|
+
}]);
|
|
2006
|
+
isUpgrade = true;
|
|
2007
|
+
waterVaporTotal += UPGRADE_WATER_VAPOR[selectedStar];
|
|
2008
|
+
ctx.logger.info(`[扰动抽卡] 卡片升级:${card.card_id},等级${currentLevel}→${currentLevel + 1}`);
|
|
2009
|
+
} else {
|
|
2010
|
+
const d = STAR_TO_DISTURBANCE[selectedStar];
|
|
2011
|
+
if (d > 0) {
|
|
2012
|
+
disturbanceTotal += d;
|
|
2013
|
+
ctx.logger.info(`[扰动抽卡] 卡片满级:${card.card_id},转化为${d}热带扰动`);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
await ctx.database.upsert("gacha_user_disturb_draw", [{ qq, draw_count: have - count }]);
|
|
2019
|
+
const asset = await ctx.database.get("gacha_user_draw_count", { qq });
|
|
2020
|
+
await ctx.database.upsert("gacha_user_draw_count", [{
|
|
2021
|
+
qq,
|
|
2022
|
+
draw_count: asset[0]?.draw_count ?? 0,
|
|
2023
|
+
tropical_disturbance: (asset[0]?.tropical_disturbance ?? 0) + disturbanceTotal,
|
|
2024
|
+
water_vapor: (asset[0]?.water_vapor ?? 0) + waterVaporTotal,
|
|
2025
|
+
no_6star_draws: asset[0]?.no_6star_draws ?? 0,
|
|
2026
|
+
no_7star_draws: asset[0]?.no_7star_draws ?? 0
|
|
2027
|
+
}]);
|
|
2028
|
+
ctx.logger.info(`[扰动抽卡] ${showName}(${qq}) 消耗${count}抽,剩余${have - count},水汽+${waterVaporTotal},热带扰动+${disturbanceTotal}`);
|
|
2029
|
+
let msg = session.text("tip.disturbDraw.title", { name: showName, left: have - count }) + "\n";
|
|
2030
|
+
drawResult.forEach((item) => {
|
|
2031
|
+
msg += `${get_star_symbol(item.star)} ${item.cid} ${item.name}
|
|
2032
|
+
`;
|
|
2033
|
+
});
|
|
2034
|
+
let info = "";
|
|
2035
|
+
if (isUpgrade) info += session.text("tip.draw.upgrade");
|
|
2036
|
+
info += session.text("tip.draw.vapor", { vapor: waterVaporTotal });
|
|
2037
|
+
info += session.text("tip.draw.disturb", { disturbanceTotal });
|
|
2038
|
+
if (info) msg += "\n" + info.replace(/;$/, "");
|
|
2039
|
+
await session.send(build_msg(session, msg));
|
|
2040
|
+
}
|
|
2041
|
+
__name(_do_disturb_draw, "_do_disturb_draw");
|
|
1897
2042
|
async function _do_broadcast(ctx, session, msg, masterQQ) {
|
|
1898
2043
|
const userQQ = await getUnifiedQQ(ctx, session);
|
|
1899
2044
|
if (userQQ !== masterQQ) return;
|
|
@@ -1945,7 +2090,7 @@ async function _do_reject(ctx, session, rejectQQ, masterQQ) {
|
|
|
1945
2090
|
}
|
|
1946
2091
|
__name(_do_reject, "_do_reject");
|
|
1947
2092
|
async function _do_help(ctx, session) {
|
|
1948
|
-
const helpMsg = session.text("command.wwc.help.title") + "\n" + session.text("command.wwc.help.register") + "\n" + session.text("command.wwc.help.sign") + "\n" + session.text("command.wwc.help.draw") + "\n" + session.text("command.wwc.help.warehouse") + "\n" + session.text("command.wwc.help.shop") + "\n" + session.text("command.wwc.help.upgrade") + "\n" + session.text("command.wwc.help.exchange") + "\n" + session.text("command.wwc.help.collection") + "\n" + session.text("command.wwc.help.ranking") + "\n" + session.text("command.wwc.help.eventStatus") + "\n" + session.text("command.wwc.help.eventDraw") + "\n" + session.text("command.wwc.help.eventExchange") + "\n" + session.text("command.wwc.help.tip");
|
|
2093
|
+
const helpMsg = session.text("command.wwc.help.title") + "\n" + session.text("command.wwc.help.register") + "\n" + session.text("command.wwc.help.sign") + "\n" + session.text("command.wwc.help.draw") + "\n" + session.text("command.wwc.help.warehouse") + "\n" + session.text("command.wwc.help.shop") + "\n" + session.text("command.wwc.help.upgrade") + "\n" + session.text("command.wwc.help.exchange") + "\n" + session.text("command.wwc.help.collection") + "\n" + session.text("command.wwc.help.ranking") + "\n" + session.text("command.wwc.help.eventStatus") + "\n" + session.text("command.wwc.help.eventDraw") + "\n" + session.text("command.wwc.help.eventExchange") + "\n" + session.text("command.wwc.help.disturbDraw") + "\n" + session.text("command.wwc.help.disturbExchange") + "\n" + session.text("command.wwc.help.tip");
|
|
1949
2094
|
await session.send(build_msg(session, helpMsg));
|
|
1950
2095
|
}
|
|
1951
2096
|
__name(_do_help, "_do_help");
|
|
@@ -2045,6 +2190,10 @@ async function apply(ctx, config) {
|
|
|
2045
2190
|
got6: { type: "boolean" },
|
|
2046
2191
|
got7: { type: "boolean" }
|
|
2047
2192
|
}, { primary: ["qq", "event_code"] });
|
|
2193
|
+
ctx.model.extend("gacha_user_disturb_draw", {
|
|
2194
|
+
qq: { type: "string" },
|
|
2195
|
+
draw_count: { type: "integer" }
|
|
2196
|
+
}, { primary: ["qq"] });
|
|
2048
2197
|
ctx.model.extend("gacha_group_member", {
|
|
2049
2198
|
group_id: { type: "string" },
|
|
2050
2199
|
qq: { type: "string" },
|
|
@@ -2230,6 +2379,20 @@ async function apply(ctx, config) {
|
|
|
2230
2379
|
const cnt = Number.isInteger(num) && num >= 1 && num <= 40 ? num : 1;
|
|
2231
2380
|
await _do_event_exchange(ctx, session, { code, cnt }, config.eventExchangePrice6, config.eventExchangePrice7);
|
|
2232
2381
|
});
|
|
2382
|
+
ctx.command("WWC扰动抽卡 [次数]", "使用扰动抽数抽卡(普通卡池:7星10%、6星36%、5星54%),支持1-20连").alias("wwc扰动抽卡").alias("WWC扰动抽").action(async (argv, count) => {
|
|
2383
|
+
if (!argv.session) return;
|
|
2384
|
+
const session = argv.session;
|
|
2385
|
+
const num = Number(count);
|
|
2386
|
+
const times = Number.isInteger(num) && num >= 1 && num <= 20 ? num : 1;
|
|
2387
|
+
await _do_disturb_draw(ctx, session, times);
|
|
2388
|
+
});
|
|
2389
|
+
ctx.command("WWC扰动兑换 <次数>", "热带扰动兑换扰动抽数,每抽消耗由配置项决定(默认100),单次1-40").alias("wwc扰动兑换").alias("WWC扰动换抽").action(async (argv, count) => {
|
|
2390
|
+
if (!argv.session) return;
|
|
2391
|
+
const session = argv.session;
|
|
2392
|
+
const num = Number(count);
|
|
2393
|
+
const cnt = Number.isInteger(num) && num >= 1 && num <= 40 ? num : 1;
|
|
2394
|
+
await _do_disturb_exchange(ctx, session, cnt, config.disturbExchangePrice);
|
|
2395
|
+
});
|
|
2233
2396
|
ctx.command("WWC限时录入 <参数...>", "录入限时卡池信息,仅主人可用(格式:期数 ID 名称 星级 类别 开始戳 结束戳)").alias("wwc限时录入").action(async (argv, ...params) => {
|
|
2234
2397
|
if (!argv.session) return;
|
|
2235
2398
|
const session = argv.session;
|
|
@@ -12,6 +12,8 @@ declare const _default: {
|
|
|
12
12
|
"command.wwc.help.eventStatus": string;
|
|
13
13
|
"command.wwc.help.eventDraw": string;
|
|
14
14
|
"command.wwc.help.eventExchange": string;
|
|
15
|
+
"command.wwc.help.disturbDraw": string;
|
|
16
|
+
"command.wwc.help.disturbExchange": string;
|
|
15
17
|
"command.wwc.help.tip": string;
|
|
16
18
|
"tip.register.success": string;
|
|
17
19
|
"tip.register.modify": string;
|
|
@@ -25,6 +27,8 @@ declare const _default: {
|
|
|
25
27
|
"tip.switch.groupClose": string;
|
|
26
28
|
"tip.eventAdd.success": string;
|
|
27
29
|
"tip.eventExchange.success": string;
|
|
30
|
+
"tip.disturbExchange.success": string;
|
|
31
|
+
"tip.disturbDraw.title": string;
|
|
28
32
|
"tip.eventStatus.info": string;
|
|
29
33
|
"tip.upgrade.success": string;
|
|
30
34
|
"tip.upgrade.cost": string;
|
|
@@ -37,6 +41,8 @@ declare const _default: {
|
|
|
37
41
|
"tip.draw.upgrade": string;
|
|
38
42
|
"tip.draw.vapor": string;
|
|
39
43
|
"tip.draw.disturb": string;
|
|
44
|
+
"tip.draw.left": string;
|
|
45
|
+
"tip.eventDraw.left": string;
|
|
40
46
|
"tip.eventDraw.pityReset": string;
|
|
41
47
|
"tip.eventDraw.pityProgress": string;
|
|
42
48
|
"error.common.noPermission": string;
|
|
@@ -69,6 +75,8 @@ declare const _default: {
|
|
|
69
75
|
"error.eventDraw.count.notEnough": string;
|
|
70
76
|
"error.eventDraw.param.invalid": string;
|
|
71
77
|
"error.eventExchange.pool.none": string;
|
|
78
|
+
"error.disturbExchange.disturb.notEnough": string;
|
|
79
|
+
"error.disturbDraw.count.notEnough": string;
|
|
72
80
|
"error.switch.private": string;
|
|
73
81
|
"error.switch.fail": string;
|
|
74
82
|
"error.shop.no7starCard": string;
|