@jeik/dingtalk-connector 0.8.21-fix1
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/CHANGELOG.md +686 -0
- package/LICENSE +21 -0
- package/README.en.md +181 -0
- package/README.md +221 -0
- package/bin/dingtalk-connector.js +858 -0
- package/bin/wizard-config.mjs +110 -0
- package/dist/accounts-BAzdqkAV.mjs +268 -0
- package/dist/accounts-BQptOmgB.mjs +2 -0
- package/dist/chunk-upload-BBQgGtcZ.mjs +193 -0
- package/dist/chunk-upload-DaLXXZH3.mjs +2 -0
- package/dist/common-C8pYKU_y.mjs +2 -0
- package/dist/common-Dt9n6fQN.mjs +101 -0
- package/dist/connection-DHHFFNQJ.mjs +423 -0
- package/dist/entry-bundled.d.mts +16 -0
- package/dist/entry-bundled.mjs +31 -0
- package/dist/game-xiyou-CqHt-6Q1.mjs +4271 -0
- package/dist/gateway-methods-C4tcgI7P.mjs +771 -0
- package/dist/gateway-methods-Ci31A3vg.mjs +2 -0
- package/dist/http-client-CpnJHB89.mjs +2 -0
- package/dist/http-client-DFWZgO1n.mjs +33 -0
- package/dist/index.d.mts +193 -0
- package/dist/index.mjs +45 -0
- package/dist/logger-BmJkQkm1.mjs +2 -0
- package/dist/logger-mZ9OSbmD.mjs +58 -0
- package/dist/media-C_SVin7s.mjs +2 -0
- package/dist/media-cz72EVS3.mjs +509 -0
- package/dist/message-handler-DESzFFDc.mjs +1971 -0
- package/dist/messaging-B6l1sRvX.mjs +1044 -0
- package/dist/runtime-DUgpo5zC.mjs +1422 -0
- package/dist/session-DJ4jYqPv.mjs +114 -0
- package/dist/utils-Bjh4r_qS.mjs +4 -0
- package/dist/utils-CIfI_3Jh.mjs +63 -0
- package/dist/utils-legacy-CALCPP1t.mjs +230 -0
- package/dist/utils-legacy-CFYDBM4r.mjs +3 -0
- package/docs/DEAP_AGENT_GUIDE.en.md +115 -0
- package/docs/DEAP_AGENT_GUIDE.md +115 -0
- package/docs/DINGTALK_MANUAL_SETUP.md +50 -0
- package/docs/MULTI_AGENT_SETUP.md +306 -0
- package/docs/RELEASE_NOTES_V0.7.10.md +40 -0
- package/docs/RELEASE_NOTES_V0.7.2.md +143 -0
- package/docs/RELEASE_NOTES_V0.7.3.md +149 -0
- package/docs/RELEASE_NOTES_V0.7.4.md +206 -0
- package/docs/RELEASE_NOTES_V0.7.5.md +267 -0
- package/docs/RELEASE_NOTES_V0.7.6.md +219 -0
- package/docs/RELEASE_NOTES_V0.7.7.md +122 -0
- package/docs/RELEASE_NOTES_V0.7.8.md +101 -0
- package/docs/RELEASE_NOTES_V0.7.9.md +65 -0
- package/docs/RELEASE_NOTES_V0.8.0.md +53 -0
- package/docs/RELEASE_NOTES_V0.8.1.md +47 -0
- package/docs/RELEASE_NOTES_V0.8.10.md +49 -0
- package/docs/RELEASE_NOTES_V0.8.11.md +51 -0
- package/docs/RELEASE_NOTES_V0.8.12.md +63 -0
- package/docs/RELEASE_NOTES_V0.8.13-beta.0.md +69 -0
- package/docs/RELEASE_NOTES_V0.8.13.md +62 -0
- package/docs/RELEASE_NOTES_V0.8.14.md +86 -0
- package/docs/RELEASE_NOTES_V0.8.16.md +40 -0
- package/docs/RELEASE_NOTES_V0.8.17.md +87 -0
- package/docs/RELEASE_NOTES_V0.8.18.md +64 -0
- package/docs/RELEASE_NOTES_V0.8.19.md +62 -0
- package/docs/RELEASE_NOTES_V0.8.2.md +55 -0
- package/docs/RELEASE_NOTES_V0.8.20.md +49 -0
- package/docs/RELEASE_NOTES_V0.8.3.md +63 -0
- package/docs/RELEASE_NOTES_V0.8.4.md +45 -0
- package/docs/RELEASE_NOTES_V0.8.7.md +49 -0
- package/docs/RELEASE_NOTES_V0.8.8.md +63 -0
- package/docs/RELEASE_NOTES_V0.8.9.md +81 -0
- package/docs/RELEASE_NOTES_v0.7.0.md +142 -0
- package/docs/RELEASE_NOTES_v0.7.1.md +74 -0
- package/docs/TROUBLESHOOTING.md +122 -0
- package/index.ts +77 -0
- package/openclaw.plugin.json +551 -0
- package/package.json +147 -0
- package/skills/dingtalk-channel-rules/SKILL.md +91 -0
- package/skills/dingtalk-troubleshoot/SKILL.md +93 -0
- package/skills/dws-cli/SKILL.md +129 -0
- package/skills/dws-cli/references/error-codes.md +95 -0
- package/skills/dws-cli/references/field-rules.md +105 -0
- package/skills/dws-cli/references/global-reference.md +104 -0
- package/skills/dws-cli/references/intent-guide.md +114 -0
- package/skills/dws-cli/references/products/aitable.md +452 -0
- package/skills/dws-cli/references/products/attendance.md +93 -0
- package/skills/dws-cli/references/products/calendar.md +217 -0
- package/skills/dws-cli/references/products/chat.md +292 -0
- package/skills/dws-cli/references/products/contact.md +108 -0
- package/skills/dws-cli/references/products/ding.md +57 -0
- package/skills/dws-cli/references/products/report.md +162 -0
- package/skills/dws-cli/references/products/simple.md +128 -0
- package/skills/dws-cli/references/products/todo.md +138 -0
- package/skills/dws-cli/references/products/workbench.md +39 -0
- package/skills/dws-cli/references/recovery-guide.md +94 -0
- package/src/channel.ts +588 -0
- package/src/config/accounts.ts +242 -0
- package/src/config/schema.ts +180 -0
- package/src/core/connection.ts +741 -0
- package/src/core/message-handler.ts +1788 -0
- package/src/core/provider.ts +111 -0
- package/src/core/state.ts +54 -0
- package/src/device-auth-config.ts +14 -0
- package/src/device-auth.ts +197 -0
- package/src/directory.ts +95 -0
- package/src/docs.ts +293 -0
- package/src/game-xiyou/achievement-engine.ts +252 -0
- package/src/game-xiyou/bounty-system.ts +315 -0
- package/src/game-xiyou/commands.ts +223 -0
- package/src/game-xiyou/drop-engine.ts +241 -0
- package/src/game-xiyou/encounter-system.ts +135 -0
- package/src/game-xiyou/escape-engine.ts +164 -0
- package/src/game-xiyou/exp-calculator.ts +139 -0
- package/src/game-xiyou/index.ts +479 -0
- package/src/game-xiyou/level-system.ts +91 -0
- package/src/game-xiyou/monster-pool.ts +180 -0
- package/src/game-xiyou/pity-counter.ts +114 -0
- package/src/game-xiyou/random-event-engine.ts +648 -0
- package/src/game-xiyou/renderer.ts +679 -0
- package/src/game-xiyou/storage.ts +218 -0
- package/src/game-xiyou/treasure-system.ts +105 -0
- package/src/game-xiyou/types.ts +582 -0
- package/src/game-xiyou/uid-resolver.ts +49 -0
- package/src/gateway-methods.ts +740 -0
- package/src/onboarding.ts +553 -0
- package/src/policy.ts +32 -0
- package/src/probe.ts +210 -0
- package/src/reply-dispatcher.ts +874 -0
- package/src/runtime.ts +32 -0
- package/src/sdk/helpers.ts +322 -0
- package/src/sdk/types.ts +519 -0
- package/src/secret-input.ts +19 -0
- package/src/services/media/audio.ts +54 -0
- package/src/services/media/chunk-upload.ts +296 -0
- package/src/services/media/common.ts +155 -0
- package/src/services/media/file.ts +75 -0
- package/src/services/media/image.ts +81 -0
- package/src/services/media/index.ts +10 -0
- package/src/services/media/video.ts +162 -0
- package/src/services/media.ts +1143 -0
- package/src/services/messaging/card.ts +604 -0
- package/src/services/messaging/index.ts +18 -0
- package/src/services/messaging/mentions.ts +267 -0
- package/src/services/messaging/send.ts +141 -0
- package/src/services/messaging.ts +1191 -0
- package/src/services/reply-markers.ts +55 -0
- package/src/targets.ts +45 -0
- package/src/types/index.ts +59 -0
- package/src/types/pdf-parse.d.ts +3 -0
- package/src/utils/agent.ts +63 -0
- package/src/utils/async.ts +51 -0
- package/src/utils/constants.ts +27 -0
- package/src/utils/http-client.ts +38 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +78 -0
- package/src/utils/session.ts +147 -0
- package/src/utils/token.ts +93 -0
- package/src/utils/utils-legacy.ts +454 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 妖怪数据池
|
|
3
|
+
*
|
|
4
|
+
* 管理所有妖怪数据,提供按品质筛选、按产品关联加权等能力。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Monster, MonsterQuality } from './types.ts';
|
|
8
|
+
import { UP_WEIGHT_MULTIPLIER, PRODUCT_WEIGHT_MULTIPLIER } from './types.ts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 妖怪数据(内联,避免运行时文件系统依赖)
|
|
12
|
+
*/
|
|
13
|
+
const allMonsters: Monster[] = [
|
|
14
|
+
// ⬜ 普通妖怪(20 只)
|
|
15
|
+
{ id: "N001", name: "巡山小妖", emoji: "👹", quality: "normal", origin: "各山洞", relatedProduct: null, captureQuote: "大王叫我来巡山~" },
|
|
16
|
+
{ id: "N002", name: "树精", emoji: "🌳", quality: "normal", origin: "荆棘岭", relatedProduct: "contact", captureQuote: "落叶归根,不过如此。" },
|
|
17
|
+
{ id: "N003", name: "草头神", emoji: "🌿", quality: "normal", origin: "通天河畔", relatedProduct: "calendar", captureQuote: "时辰到了,该走了。" },
|
|
18
|
+
{ id: "N004", name: "虾兵", emoji: "🦐", quality: "normal", origin: "东海", relatedProduct: "chat", captureQuote: "龙宫不是你想来就能来的!" },
|
|
19
|
+
{ id: "N005", name: "蟹将", emoji: "🦀", quality: "normal", origin: "东海", relatedProduct: "chat", captureQuote: "横行霸道?那是我的专利。" },
|
|
20
|
+
{ id: "N006", name: "山神", emoji: "⛰️", quality: "normal", origin: "各处", relatedProduct: "attendance", captureQuote: "此山是我开,此树是我栽。" },
|
|
21
|
+
{ id: "N007", name: "土地公", emoji: "👴", quality: "normal", origin: "各处", relatedProduct: "contact", captureQuote: "大圣饶命,小神知无不言。" },
|
|
22
|
+
{ id: "N008", name: "夜叉", emoji: "👿", quality: "normal", origin: "水府", relatedProduct: "ding", captureQuote: "水底的消息,最快。" },
|
|
23
|
+
{ id: "N009", name: "狼妖", emoji: "🐺", quality: "normal", origin: "黄风岭", relatedProduct: "todo", captureQuote: "待办事项?我只待吃人。" },
|
|
24
|
+
{ id: "N010", name: "蛇妖", emoji: "🐍", quality: "normal", origin: "蛇盘山", relatedProduct: "devdoc", captureQuote: "嘶——文档里藏着秘密。" },
|
|
25
|
+
{ id: "N011", name: "鹿精", emoji: "🦌", quality: "normal", origin: "比丘国", relatedProduct: "report", captureQuote: "今日份的鹿茸报告。" },
|
|
26
|
+
{ id: "N012", name: "兔精", emoji: "🐇", quality: "normal", origin: "天竺国", relatedProduct: "calendar", captureQuote: "月宫的日程,排得满满的。" },
|
|
27
|
+
{ id: "N013", name: "鱼精", emoji: "🐟", quality: "normal", origin: "通天河", relatedProduct: "aitable", captureQuote: "河底的账本,一条不差。" },
|
|
28
|
+
{ id: "N014", name: "龟精", emoji: "🐢", quality: "normal", origin: "通天河", relatedProduct: "todo", captureQuote: "慢是慢了点,但待办一定完成。" },
|
|
29
|
+
{ id: "N015", name: "猪妖", emoji: "🐷", quality: "normal", origin: "福陵山", relatedProduct: "report", captureQuote: "日报?让我先睡一觉再说。" },
|
|
30
|
+
{ id: "N016", name: "鸡精", emoji: "🐔", quality: "normal", origin: "毒敌山", relatedProduct: "attendance", captureQuote: "打鸣就是打卡,准时得很。" },
|
|
31
|
+
{ id: "N017", name: "鼠精", emoji: "🐭", quality: "normal", origin: "无底洞", relatedProduct: "aitable", captureQuote: "数据?我最擅长搬运了。" },
|
|
32
|
+
{ id: "N018", name: "蝙蝠精", emoji: "🦇", quality: "normal", origin: "黄花观", relatedProduct: "ding", captureQuote: "暗夜传信,无声无息。" },
|
|
33
|
+
{ id: "N019", name: "石妖", emoji: "🪨", quality: "normal", origin: "花果山", relatedProduct: "workbench", captureQuote: "石头里蹦出来的,不止猴子。" },
|
|
34
|
+
{ id: "N020", name: "柳树精", emoji: "🌾", quality: "normal", origin: "荆棘岭", relatedProduct: "approval", captureQuote: "柳条一挥,审批盖章。" },
|
|
35
|
+
// 🟢 精良妖怪(15 只)
|
|
36
|
+
{ id: "R001", name: "黑风怪", emoji: "🐻", quality: "fine", origin: "黑风山", relatedProduct: "workbench", captureQuote: "这袈裟,归我了!" },
|
|
37
|
+
{ id: "R002", name: "黄风怪", emoji: "🐀", quality: "fine", origin: "黄风岭", relatedProduct: "chat", captureQuote: "三昧神风,吹!" },
|
|
38
|
+
{ id: "R003", name: "白骨精", emoji: "💀", quality: "fine", origin: "白虎岭", relatedProduct: "contact", captureQuote: "变化之术,通讯录里谁是谁?" },
|
|
39
|
+
{ id: "R004", name: "银角大王", emoji: "🦊", quality: "fine", origin: "平顶山", relatedProduct: "aitable", captureQuote: "紫金红葫芦,装!" },
|
|
40
|
+
{ id: "R005", name: "金角大王", emoji: "🦁", quality: "fine", origin: "平顶山", relatedProduct: "aitable", captureQuote: "幌金绳,捆!" },
|
|
41
|
+
{ id: "R006", name: "红孩儿", emoji: "🔥", quality: "fine", origin: "火云洞", relatedProduct: "ding", captureQuote: "三昧真火,DING!" },
|
|
42
|
+
{ id: "R007", name: "鼍龙", emoji: "🐊", quality: "fine", origin: "黑水河", relatedProduct: "approval", captureQuote: "我舅舅是西海龙王,审批通过!" },
|
|
43
|
+
{ id: "R008", name: "蜘蛛精", emoji: "🕷️", quality: "fine", origin: "盘丝洞", relatedProduct: "todo", captureQuote: "七姐妹的待办,丝丝入扣。" },
|
|
44
|
+
{ id: "R009", name: "蝎子精", emoji: "🦂", quality: "fine", origin: "琵琶洞", relatedProduct: "attendance", captureQuote: "倒马毒桩,准时打卡。" },
|
|
45
|
+
{ id: "R010", name: "六耳猕猴", emoji: "🐵", quality: "fine", origin: "—", relatedProduct: null, captureQuote: "真假难辨,你猜我是谁?" },
|
|
46
|
+
{ id: "R011", name: "奔波儿灞", emoji: "🐡", quality: "fine", origin: "乱石山碧波潭", relatedProduct: "chat", captureQuote: "跑腿送信,我最在行。" },
|
|
47
|
+
{ id: "R012", name: "灞波儿奔", emoji: "🐠", quality: "fine", origin: "乱石山碧波潭", relatedProduct: "chat", captureQuote: "消息必达,使命必成。" },
|
|
48
|
+
{ id: "R013", name: "独角兕大王", emoji: "🦏", quality: "fine", origin: "金兜山", relatedProduct: "calendar", captureQuote: "金刚琢套住你的日程。" },
|
|
49
|
+
{ id: "R014", name: "如意真仙", emoji: "🧙", quality: "fine", origin: "解阳山", relatedProduct: "report", captureQuote: "落胎泉的日报,概不外传。" },
|
|
50
|
+
{ id: "R015", name: "虎力大仙", emoji: "🐯", quality: "fine", origin: "车迟国", relatedProduct: "approval", captureQuote: "国师审批,一言九鼎。" },
|
|
51
|
+
// 🔵 稀有妖怪(12 只)
|
|
52
|
+
{ id: "S001", name: "黄袍怪", emoji: "🐆", quality: "rare", origin: "碗子山", relatedProduct: "report", captureQuote: "百花羞的日报,我替她写了。" },
|
|
53
|
+
{ id: "S002", name: "金翅大鹏", emoji: "🦅", quality: "rare", origin: "狮驼岭", relatedProduct: "calendar", captureQuote: "翅膀一扇,九万里。日程?不存在的。" },
|
|
54
|
+
{ id: "S003", name: "青牛精", emoji: "🐂", quality: "rare", origin: "金兜山", relatedProduct: "aitable", captureQuote: "金刚琢,套住你的表格。" },
|
|
55
|
+
{ id: "S004", name: "铁扇公主", emoji: "🪭", quality: "rare", origin: "翠云山", relatedProduct: "approval", captureQuote: "芭蕉扇一扇,审批全灭。" },
|
|
56
|
+
{ id: "S005", name: "牛魔王", emoji: "🐃", quality: "rare", origin: "积雷山", relatedProduct: "workbench", captureQuote: "我乃平天大圣,工作台归我管。" },
|
|
57
|
+
{ id: "S006", name: "白鹿精", emoji: "🫎", quality: "rare", origin: "比丘国", relatedProduct: "attendance", captureQuote: "一千一百一十一个小儿的考勤。" },
|
|
58
|
+
{ id: "S007", name: "蜈蚣精", emoji: "🐛", quality: "rare", origin: "黄花观", relatedProduct: "todo", captureQuote: "千目待办,一个不漏。" },
|
|
59
|
+
{ id: "S008", name: "玉兔精", emoji: "🐰", quality: "rare", origin: "天竺国", relatedProduct: "calendar", captureQuote: "广寒宫的排班表,我说了算。" },
|
|
60
|
+
{ id: "S009", name: "金鼻白毛老鼠精", emoji: "🐁", quality: "rare", origin: "无底洞", relatedProduct: "contact", captureQuote: "无底洞的通讯录,深不见底。" },
|
|
61
|
+
{ id: "S010", name: "鹿力大仙", emoji: "🦬", quality: "rare", origin: "车迟国", relatedProduct: "ding", captureQuote: "呼风唤雨,DING 声如雷。" },
|
|
62
|
+
{ id: "S011", name: "羊力大仙", emoji: "🐏", quality: "rare", origin: "车迟国", relatedProduct: "devdoc", captureQuote: "油锅里的文档,捞出来就是。" },
|
|
63
|
+
{ id: "S012", name: "荆棘岭十八公", emoji: "🌲", quality: "rare", origin: "荆棘岭", relatedProduct: "chat", captureQuote: "松竹梅桂,群聊四友。" },
|
|
64
|
+
// 🟣 史诗妖怪(10 只)
|
|
65
|
+
{ id: "E001", name: "黄眉大王", emoji: "👺", quality: "epic", origin: "弥勒佛的童子", relatedProduct: "approval", captureQuote: "人种袋,把你的审批全装进来。" },
|
|
66
|
+
{ id: "E002", name: "大鹏金翅明王", emoji: "🦤", quality: "epic", origin: "如来舅舅", relatedProduct: "workbench", captureQuote: "狮驼国的工作台,三界最大。" },
|
|
67
|
+
{ id: "E003", name: "九灵元圣", emoji: "🦁", quality: "epic", origin: "太乙天尊坐骑", relatedProduct: "aitable", captureQuote: "九个头,九张表,哪个都不能少。" },
|
|
68
|
+
{ id: "E004", name: "赛太岁", emoji: "🐕", quality: "epic", origin: "观音坐骑金毛犼", relatedProduct: "attendance", captureQuote: "紫金铃一摇,全员到齐。" },
|
|
69
|
+
{ id: "E005", name: "青狮精", emoji: "🦁", quality: "epic", origin: "文殊菩萨坐骑", relatedProduct: "chat", captureQuote: "狮子吼,群消息已送达。" },
|
|
70
|
+
{ id: "E006", name: "白象精", emoji: "🐘", quality: "epic", origin: "普贤菩萨坐骑", relatedProduct: "todo", captureQuote: "长鼻一卷,待办清空。" },
|
|
71
|
+
{ id: "E007", name: "蠹虫精", emoji: "🪲", quality: "epic", origin: "比丘国国丈", relatedProduct: "report", captureQuote: "一千一百一十一份日报,全在这了。" },
|
|
72
|
+
{ id: "E008", name: "金鱼精", emoji: "🐠", quality: "epic", origin: "观音莲花池", relatedProduct: "calendar", captureQuote: "通天河的日程,年年祭祀。" },
|
|
73
|
+
{ id: "E009", name: "蟒蛇精", emoji: "🐉", quality: "epic", origin: "七绝山", relatedProduct: "devdoc", captureQuote: "七绝山的文档,毒气弥漫。" },
|
|
74
|
+
{ id: "E010", name: "灵感大王", emoji: "🐋", quality: "epic", origin: "通天河", relatedProduct: "ding", captureQuote: "金鱼一跃,DING 达四海。" },
|
|
75
|
+
// 🟡 传说妖怪(8 只)
|
|
76
|
+
{ id: "L001", name: "混世魔王", emoji: "👑", quality: "legendary", origin: "花果山第一战", relatedProduct: null, captureQuote: "水帘洞,从此姓孙。" },
|
|
77
|
+
{ id: "L002", name: "牛魔王(魔化)", emoji: "🔱", quality: "legendary", origin: "大力牛魔王本相", relatedProduct: null, captureQuote: "平天大圣,不服来战!" },
|
|
78
|
+
{ id: "L003", name: "九头虫", emoji: "🐲", quality: "legendary", origin: "碧波潭万圣龙王驸马", relatedProduct: null, captureQuote: "九颗头颅,九种权限。" },
|
|
79
|
+
{ id: "L004", name: "百眼魔君", emoji: "👁️", quality: "legendary", origin: "蜈蚣精本相", relatedProduct: null, captureQuote: "千目金光,洞察一切数据。" },
|
|
80
|
+
{ id: "L005", name: "大鹏金翅(本相)", emoji: "🦅", quality: "legendary", origin: "遮天蔽日", relatedProduct: null, captureQuote: "三界之大,不过我翅膀之下。" },
|
|
81
|
+
{ id: "L006", name: "孙悟空(石猴)", emoji: "🐒", quality: "legendary", origin: "花果山水帘洞", relatedProduct: null, captureQuote: "俺老孙来也!" },
|
|
82
|
+
{ id: "L007", name: "六耳猕猴(真身)", emoji: "🙈", quality: "legendary", origin: "混沌之中", relatedProduct: null, captureQuote: "天地间第二个齐天大圣。" },
|
|
83
|
+
{ id: "L008", name: "白骨夫人(真身)", emoji: "☠️", quality: "legendary", origin: "白虎岭深处", relatedProduct: null, captureQuote: "三打不死,方显真身。" },
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 获取所有妖怪
|
|
88
|
+
*/
|
|
89
|
+
export function getAllMonsters(): Monster[] {
|
|
90
|
+
return allMonsters;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 获取指定品质的妖怪列表
|
|
95
|
+
*/
|
|
96
|
+
export function getMonstersByQuality(quality: MonsterQuality): Monster[] {
|
|
97
|
+
return allMonsters.filter(m => m.quality === quality);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 根据 ID 查找妖怪
|
|
102
|
+
*/
|
|
103
|
+
export function getMonsterById(monsterId: string): Monster | undefined {
|
|
104
|
+
return allMonsters.find(m => m.id === monsterId);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 获取所有妖怪的总数(不含闪光变体)
|
|
109
|
+
*/
|
|
110
|
+
export function getTotalMonsterCount(): number {
|
|
111
|
+
return allMonsters.length;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 获取本周 UP 妖怪
|
|
116
|
+
*
|
|
117
|
+
* 按周数轮换,从史诗和传说池中选择
|
|
118
|
+
*/
|
|
119
|
+
export function getWeeklyUpMonster(): Monster | null {
|
|
120
|
+
const upPool = allMonsters.filter(
|
|
121
|
+
m => m.quality === 'epic' || m.quality === 'legendary'
|
|
122
|
+
);
|
|
123
|
+
if (upPool.length === 0) return null;
|
|
124
|
+
|
|
125
|
+
const weekNumber = Math.floor(Date.now() / (7 * 24 * 60 * 60 * 1000));
|
|
126
|
+
const index = weekNumber % upPool.length;
|
|
127
|
+
return upPool[index];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 带权重的随机选择妖怪
|
|
132
|
+
*
|
|
133
|
+
* @param pool - 候选妖怪池
|
|
134
|
+
* @param product - 当前 dws 产品(关联产品权重 ×3)
|
|
135
|
+
* @param upMonster - 本周 UP 妖怪(权重 ×5)
|
|
136
|
+
* @param randomValue - 随机数 [0, 1)
|
|
137
|
+
*/
|
|
138
|
+
export function weightedRandomSelect(
|
|
139
|
+
pool: Monster[],
|
|
140
|
+
product: string | null,
|
|
141
|
+
upMonster: Monster | null,
|
|
142
|
+
randomValue: number
|
|
143
|
+
): Monster {
|
|
144
|
+
if (pool.length === 0) {
|
|
145
|
+
throw new Error('Monster pool is empty');
|
|
146
|
+
}
|
|
147
|
+
if (pool.length === 1) {
|
|
148
|
+
return pool[0];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 计算每只妖怪的权重
|
|
152
|
+
const weights = pool.map(monster => {
|
|
153
|
+
let weight = 1;
|
|
154
|
+
|
|
155
|
+
// 产品关联加权
|
|
156
|
+
if (product && monster.relatedProduct === product) {
|
|
157
|
+
weight *= PRODUCT_WEIGHT_MULTIPLIER;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// UP 池加权
|
|
161
|
+
if (upMonster && monster.id === upMonster.id) {
|
|
162
|
+
weight *= UP_WEIGHT_MULTIPLIER;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return weight;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// 加权随机选择
|
|
169
|
+
const totalWeight = weights.reduce((sum, w) => sum + w, 0);
|
|
170
|
+
let target = randomValue * totalWeight;
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < pool.length; i++) {
|
|
173
|
+
target -= weights[i];
|
|
174
|
+
if (target <= 0) {
|
|
175
|
+
return pool[i];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return pool[pool.length - 1];
|
|
180
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 保底计数器
|
|
3
|
+
*
|
|
4
|
+
* 借鉴 Gacha 游戏的保底设计,防止"非酋"体验过差。
|
|
5
|
+
* v2: 保底阈值全面上调 + 软保底机制(接近硬保底时概率逐步提升)。
|
|
6
|
+
* 保底计数器在对应品质或更高品质掉落后重置。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { PityCounters, MonsterQuality } from './types.ts';
|
|
10
|
+
import {
|
|
11
|
+
PITY_THRESHOLDS, QUALITY_ORDER,
|
|
12
|
+
SOFT_PITY_START, SOFT_PITY_RATE_PER_STEP,
|
|
13
|
+
} from './types.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 检查是否触发硬保底,返回应强制掉落的品质(如果有)
|
|
17
|
+
*/
|
|
18
|
+
export function checkPityTrigger(counters: PityCounters): MonsterQuality | null {
|
|
19
|
+
if (counters.totalDropsWithoutShiny >= PITY_THRESHOLDS.shiny) {
|
|
20
|
+
return 'shiny';
|
|
21
|
+
}
|
|
22
|
+
if (counters.sinceLastLegendary >= PITY_THRESHOLDS.legendary) {
|
|
23
|
+
return 'legendary';
|
|
24
|
+
}
|
|
25
|
+
if (counters.sinceLastEpic >= PITY_THRESHOLDS.epic) {
|
|
26
|
+
return 'epic';
|
|
27
|
+
}
|
|
28
|
+
if (counters.sinceLastRare >= PITY_THRESHOLDS.rare) {
|
|
29
|
+
return 'rare';
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* v2: 计算软保底额外概率加成
|
|
36
|
+
*
|
|
37
|
+
* 在接近硬保底阈值时,对应品质的掉落概率逐步提升,
|
|
38
|
+
* 避免"临门一脚"的漫长等待。
|
|
39
|
+
*
|
|
40
|
+
* @returns 各品质的额外概率加成 { rare: 0.06, epic: 0, ... }
|
|
41
|
+
*/
|
|
42
|
+
export function getSoftPityBonuses(counters: PityCounters): Partial<Record<MonsterQuality, number>> {
|
|
43
|
+
const bonuses: Partial<Record<MonsterQuality, number>> = {};
|
|
44
|
+
|
|
45
|
+
// 稀有软保底:第 20 次起,每次额外 +3%
|
|
46
|
+
if (counters.sinceLastRare >= SOFT_PITY_START.rare) {
|
|
47
|
+
const steps = counters.sinceLastRare - SOFT_PITY_START.rare;
|
|
48
|
+
bonuses.rare = steps * SOFT_PITY_RATE_PER_STEP.rare;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 史诗软保底:第 60 次起,每次额外 +2%
|
|
52
|
+
if (counters.sinceLastEpic >= SOFT_PITY_START.epic) {
|
|
53
|
+
const steps = counters.sinceLastEpic - SOFT_PITY_START.epic;
|
|
54
|
+
bonuses.epic = steps * SOFT_PITY_RATE_PER_STEP.epic;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 传说软保底:第 120 次起,每次额外 +1%
|
|
58
|
+
if (counters.sinceLastLegendary >= SOFT_PITY_START.legendary) {
|
|
59
|
+
const steps = counters.sinceLastLegendary - SOFT_PITY_START.legendary;
|
|
60
|
+
bonuses.legendary = steps * SOFT_PITY_RATE_PER_STEP.legendary;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 闪光软保底:第 600 次起,每次额外 +0.05%
|
|
64
|
+
if (counters.totalDropsWithoutShiny >= SOFT_PITY_START.shiny) {
|
|
65
|
+
const steps = counters.totalDropsWithoutShiny - SOFT_PITY_START.shiny;
|
|
66
|
+
bonuses.shiny = steps * SOFT_PITY_RATE_PER_STEP.shiny;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return bonuses;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 更新保底计数器
|
|
74
|
+
*
|
|
75
|
+
* 掉落后递增所有计数器,然后重置对应品质及以下的计数器
|
|
76
|
+
*/
|
|
77
|
+
export function updatePityCounters(counters: PityCounters, droppedQuality: MonsterQuality, isShiny: boolean): void {
|
|
78
|
+
// 递增所有计数器
|
|
79
|
+
counters.sinceLastRare += 1;
|
|
80
|
+
counters.sinceLastEpic += 1;
|
|
81
|
+
counters.sinceLastLegendary += 1;
|
|
82
|
+
counters.totalDropsWithoutShiny += 1;
|
|
83
|
+
|
|
84
|
+
// 根据掉落品质重置对应计数器
|
|
85
|
+
const qualityIndex = QUALITY_ORDER.indexOf(droppedQuality);
|
|
86
|
+
|
|
87
|
+
if (isShiny || droppedQuality === 'shiny') {
|
|
88
|
+
counters.totalDropsWithoutShiny = 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (qualityIndex >= QUALITY_ORDER.indexOf('legendary')) {
|
|
92
|
+
counters.sinceLastLegendary = 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (qualityIndex >= QUALITY_ORDER.indexOf('epic')) {
|
|
96
|
+
counters.sinceLastEpic = 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (qualityIndex >= QUALITY_ORDER.indexOf('rare')) {
|
|
100
|
+
counters.sinceLastRare = 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 应用保底减半 buff(观音菩萨收徒效果)
|
|
106
|
+
*/
|
|
107
|
+
export function applyPityReduction(counters: PityCounters, reductionFactor: number): PityCounters {
|
|
108
|
+
return {
|
|
109
|
+
sinceLastRare: Math.floor(counters.sinceLastRare * reductionFactor),
|
|
110
|
+
sinceLastEpic: Math.floor(counters.sinceLastEpic * reductionFactor),
|
|
111
|
+
sinceLastLegendary: Math.floor(counters.sinceLastLegendary * reductionFactor),
|
|
112
|
+
totalDropsWithoutShiny: Math.floor(counters.totalDropsWithoutShiny * reductionFactor),
|
|
113
|
+
};
|
|
114
|
+
}
|