From 6e1b63659cb133b4d8a780e28c49bb433e18b052 Mon Sep 17 00:00:00 2001 From: Ulysses Zhan Date: Sun, 31 Dec 2023 17:17:10 -0800 Subject: [PATCH] add dan; add typing time cap --- data/config.yml | 1 + data/configCN.yml | 1 + data/dan.yml | 339 +++++++++++++++++++++++++++++++++++++++++ lib/lyricat.rb | 1 + lib/lyricat/bot.rb | 65 +++++--- lib/lyricat/dan.rb | 42 +++++ lib/lyricat/version.rb | 2 +- 7 files changed, 429 insertions(+), 22 deletions(-) create mode 100644 data/dan.yml create mode 100644 lib/lyricat/dan.rb diff --git a/data/config.yml b/data/config.yml index 2829a03..fd7a5e5 100644 --- a/data/config.yml +++ b/data/config.yml @@ -13,3 +13,4 @@ res: lyrics: sheet/LyricsSheet.asset prefix: '!' expiration_margin: 60000 # in ms +max_typing_time: 30 # in s diff --git a/data/configCN.yml b/data/configCN.yml index c696582..cb3dc47 100644 --- a/data/configCN.yml +++ b/data/configCN.yml @@ -13,3 +13,4 @@ res: lyrics: sheet/LyricsSheetCN.asset prefix: '?' expiration_margin: 60000 # in ms +max_typing_time: 30 # in s diff --git a/data/dan.yml b/data/dan.yml new file mode 100644 index 0000000..d5a75b3 --- /dev/null +++ b/data/dan.yml @@ -0,0 +1,339 @@ +--- +- index: 1 + levels: + - - song_id: 6 # 饮茶 + diff_id: 4 + - song_id: 91 # 鸟鸣涧 + diff_id: 4 + - song_id: 34 # 月夜 + diff_id: 4 + - song_id: 104 # VUVU + diff_id: 3 + - - song_id: 36 # 离离 + diff_id: 4 + - song_id: 29 # 绣阁里 + diff_id: 4 + - song_id: 44 # 乌衣巷 + diff_id: 4 + - song_id: 87 # 嫁衣 + diff_id: 3 + health: 50 + heal: 20 + judgement: 3 +- index: 2 + levels: + - - song_id: 4 # 清平调 + diff_id: 4 + - song_id: 66 # 玉楼春 交响 + diff_id: 3 + - song_id: 84 # 唐多令 + diff_id: 3 + - song_id: 102 # 颂赞日 + diff_id: 3 + - - song_id: 39 # 偶成冬夜 + diff_id: 4 + - song_id: 67 # 木兰 交响 + diff_id: 3 + - song_id: 162 # 秋殇 + diff_id: 3 + - song_id: 111 # Matane + diff_id: 3 + health: 40 + heal: 15 + judgement: 3 +- index: 3 + levels: + - - song_id: 58 # 东城 + diff_id: 4 + - song_id: 48 # 户惑 + diff_id: 4 + - song_id: 13 # 马上回家 + diff_id: 4 + - song_id: 76 # 烟锁秦楼 + diff_id: 3 + - - song_id: 151 # 酒中仙 + diff_id: 3 + - song_id: 20 # 思念 + diff_id: 4 + - song_id: 60 # 寂寞达达 + diff_id: 4 + - song_id: 79 # 伤瘾 + diff_id: 3 + health: 30 + heal: 10 + judgement: 3 +- index: 4 + levels: + - - song_id: 171 # 听风听雨 + diff_id: 4 + - song_id: 51 # 待 + diff_id: 4 + - song_id: 88 # 花开花落 + diff_id: 4 + - song_id: 37 # 新劝学文 + diff_id: 3 + - - song_id: 152 # 莲城诀 + diff_id: 4 + - song_id: 170 # 君问归期 + diff_id: 4 + - song_id: 38 # 为你一直继续 + diff_id: 4 + - song_id: 30 # 白日梦 + diff_id: 3 + health: 20 + heal: 5 + judgement: 3 +- index: 5 + levels: + - - song_id: 1 # 玉楼春 + diff_id: 4 + - song_id: 95 # 八阵赋 + diff_id: 3 + - song_id: 52 # 柳永 + diff_id: 4 + - song_id: 31 # 那茶那塔 + diff_id: 4 + - - song_id: 85 # 大酺春雨 + diff_id: 4 + - song_id: 137 # 长相思 + diff_id: 3 + - song_id: 90 # 锦瑟 + diff_id: 4 + - song_id: 35 # 定风波 + diff_id: 4 + health: 10 + heal: 0 + judgement: 3 +- index: 6 + levels: + - - song_id: 112 # Prism + diff_id: 3 + - song_id: 55 # 战神卸甲 + diff_id: 4 + - song_id: 160 # 谷底绽放 + diff_id: 4 + - song_id: 0 # 还记得他曾说 + diff_id: 4 + - - song_id: 167 # 登楼之顶 + diff_id: 3 + - song_id: 43 # 宿醉 + diff_id: 4 + - song_id: 105 # 月满西楼 + diff_id: 4 + - song_id: 33 # 静水山幽 + diff_id: 4 + health: 50 + heal: 20 + judgement: 2 +- index: 7 + levels: + - - song_id: 10 # 出关 + diff_id: 4 + - song_id: 7 # 木兰 + diff_id: 4 + - song_id: 153 # Ailurophile + diff_id: 3 + - song_id: 49 # 一坨日文终 + diff_id: 4 + - - song_id: 56 # 满江红 + diff_id: 3 + - song_id: 16 # 江城子 + diff_id: 4 + - song_id: 180 # Holic My Way + diff_id: 4 + - song_id: 32 # 淇奧 + diff_id: 4 + health: 40 + heal: 15 + judgement: 2 +- index: 8 + levels: + - - song_id: 62 # 月相思 + diff_id: 4 + - song_id: 96 # 三国一梦 + diff_id: 3 + - song_id: 42 # 将进酒 + diff_id: 4 + - song_id: 14 # 上邪 + diff_id: 4 + - - song_id: 151 # 酒中仙 + diff_id: 4 + - song_id: 64 # 情钟 + diff_id: 4 + - song_id: 135 # 闲适 + diff_id: 4 + - song_id: 108 # Chronosis Song + diff_id: 4 + health: 30 + heal: 10 + judgement: 2 +- index: 9 + levels: + - - song_id: 167 # 登楼之顶 + diff_id: 4 + - song_id: 161 # 灼灼人间色 + diff_id: 4 + - song_id: 143 # 心际之旅 + diff_id: 4 + - song_id: 40 # 荒芜中的路 + diff_id: 4 + - - song_id: 117 # Maximum + diff_id: 3 + - song_id: 185 # 天仙子 + diff_id: 4 + - song_id: 104 # VUVU + diff_id: 4 + - song_id: 63 # 郎君梦 + diff_id: 4 + health: 20 + heal: 5 + judgement: 2 +- index: 10 + levels: + - - song_id: 94 # 三分天下计 + diff_id: 3 + - song_id: 57 # 闺怨 + diff_id: 4 + - song_id: 145 # 和昨日说再见 + diff_id: 4 + - song_id: 99 # 拿么美好 + diff_id: 4 + - - song_id: 18 # 莲想 + diff_id: 4 + - song_id: 136 # 失眠 + diff_id: 4 + - song_id: 137 # 长相思 + diff_id: 4 + - song_id: 87 # 嫁衣 + diff_id: 4 + health: 10 + heal: 0 + judgement: 2 +- index: 11 + levels: + - - song_id: 130 # 八十始得归 + diff_id: 4 + - song_id: 166 # 陋室铭 + diff_id: 4 + - song_id: 30 # 白日梦 + diff_id: 4 + - song_id: 107 # Apocalypse + diff_id: 4 + - - song_id: 127 # 离度 + diff_id: 4 + - song_id: 114 # Tokyo Snorkel + diff_id: 4 + - song_id: 191 # nannde + diff_id: 4 + - song_id: 67 # 木兰 交响 + diff_id: 4 + health: 70 + heal: 20 + judgement: 1 +- index: 12 + levels: + - - song_id: 50 # 30mm + diff_id: 4 + - song_id: 32 # 淇奥 + diff_id: 5 + - song_id: 173 # 大道之行 + diff_id: 4 + - song_id: 121 # Lasting Wonderworld + diff_id: 4 + - - song_id: 163 # 仲谋 + diff_id: 4 + - song_id: 113 # Raise + diff_id: 4 + - song_id: 101 # 一起一起 + diff_id: 4 + - song_id: 81 # 一剪梅 + diff_id: 4 + health: 60 + heal: 15 + judgement: 1 +- index: 13 + levels: + - - song_id: 162 # 秋殇 + diff_id: 4 + - song_id: 205 # Psyched Fevereiro + diff_id: 4 + - song_id: 197 # Desetr0yer + diff_id: 4 + - song_id: 204 # Chartreuse Green + diff_id: 4 + - - song_id: 112 # Prism + diff_id: 4 + - song_id: 155 # Eudoraa + diff_id: 4 + - song_id: 195 # Flying Springtime + diff_id: 4 + - song_id: 109 # Glamorous Girl + diff_id: 4 + health: 55 + heal: 10 + judgement: 1 +- index: 14 + levels: + - - song_id: 153 # Ailurophile + diff_id: 4 + - song_id: 206 # Mountain Eater + diff_id: 4 + - song_id: 93 # 长坂行 + diff_id: 4 + - song_id: 109 # Glamorous Girl + diff_id: 5 + health: 50 + heal: 5 + judgement: 1 +- index: 15 + levels: + - - song_id: 56 # 满江红 + diff_id: 4 + - song_id: 154 # Arrhythmia + diff_id: 4 + - song_id: 194 # Fell My Happiness + diff_id: 4 + - song_id: 114 # Tokyo Snorkel + diff_id: 5 + health: 45 + heal: 0 + judgement: 1 +- index: 16 + levels: + - - song_id: 118 # As!anTech + diff_id: 4 + - song_id: 50 # 30mm + diff_id: 5 + - song_id: 84 # 唐多令 + diff_id: 5 + - song_id: 157 # 一堆日文 feat.Yaki + diff_id: 5 + health: 40 + heal: 0 + judgement: 1 +- index: 17 + levels: + - - song_id: 94 # 三分天下计 + diff_id: 4 + - song_id: 193 # conflict + diff_id: 5 + - song_id: 192 # 竹 + diff_id: 4 + - song_id: 82 # 买花 + diff_id: 5 + health: 35 + heal: 0 + judgement: 1 +- index: 18 + levels: + - - song_id: 116 # Hex + diff_id: 4 + - song_id: 117 # Max + diff_id: 4 + - song_id: 115 # Butterfly Dance + diff_id: 5 + - song_id: 121 # Lasting Wonderworld + diff_id: 5 + health: 30 + heal: 0 + judgement: 1 diff --git a/lib/lyricat.rb b/lib/lyricat.rb index ce34f3a..2dd0be3 100644 --- a/lib/lyricat.rb +++ b/lib/lyricat.rb @@ -37,4 +37,5 @@ def self.sheet symbol require 'lyricat/heavylifting' require 'lyricat/singer' require 'lyricat/song' +require 'lyricat/dan' require 'lyricat/bot' diff --git a/lib/lyricat/bot.rb b/lib/lyricat/bot.rb index 6bff83b..465937a 100644 --- a/lib/lyricat/bot.rb +++ b/lib/lyricat/bot.rb @@ -16,6 +16,8 @@ def self.run BOT.run end + MAX_TYPING_TIME = CONFIG[:max_typing_time] || 30 + EXPIRATION_MARGIN = CONFIG[:expiration_margin] MAINTAINER_ID = ENV['LYRICAT_DISCORD_MAINTAINER_ID'] || 0 @@ -36,7 +38,7 @@ def dynamic_command name, **opts, &block def command *args, **opts, &block super *args, **opts do |event, *query| typing_thread = Thread.new do - loop do + (MAX_TYPING_TIME / 4).floor.times do event.channel.start_typing sleep 4 end @@ -167,11 +169,17 @@ def gen_multilingual_dynamic_commands name, aliases: [], **opts, &block Use the command `help bind` to see how to use it. INFO mr: <<~INFO, - 月韵 (MR) 是 5.0 版本引入的用于衡量玩家水平的一个数。 - 总 MR 的计算方式如下: - - 计算所有谱面的单谱 MR, 并对每首歌曲的各难度谱面 (除 Frog Rappa 稀世以外) 的单谱 MR 取最大的一个作为该歌曲的单谱 MR。 - - 对所有 5.0 前的歌曲中单谱 MR 最高的 35 个 (旧 b35), 以及 5.0后的歌曲中单谱 MR 的最高的 15 个 (新 b15), 取平均值获得总 MR。 - 单谱 MR 的计算公式: + **Calculation of MR** + Calculate the single-chart MR for each chart, \ + and then for each song, among all its charts (accept Frog Rappa Special), \ + pick the one with the highest single-chart MR as the single-song MR of the song. \ + Among songs before 5.0, pick 35 ones (called **b35**) \ + with the highest single-song MRs. \ + Among songs after 5.0, pick 15 ones (called **b15**) \ + with the highest single-song MRs. \ + Then, the average single-song MRs of all the 50 songs (called **b50**) \ + is the total MR of the player. + The calculation of the single-chart MR is as follows: ``` S' = S / 10000 M = { @@ -179,23 +187,22 @@ def gen_multilingual_dynamic_commands name, aliases: [], **opts, &block max(0, d+1 - (98-S')/4), if 50 <= S' <= 98; d+2 - (100-S')/2, if S' >= 98 } - ``` - 其中S为分数,d为单谱定数 + ```where `S` is the score, and `d` is the difficulty. INFO dan: <<~INFO, - 阳春白雪/阳春艺曲晋升之路(非官方)规则如下: - 1. 血量上限即为初始血量,挑战过程中任何时刻血量归0即为挑战失败。 - 2. 扣血标准指每出现一个指定判定或以下则血量-1。 - 3. 回复血量指当前晋升之路挑战中每通过一首歌所回复的血量(最后一首不回复)。 - 4. 挑战关卡时,需要连续通过指定的四首歌曲,中间不能重试。若所挑战关卡有两组歌曲,则任选其一通过即算通过该关卡。 - 5. 在结束四首晋升之路挑战歌曲之后算出(残余血量/血量上限x100%)得出的值与通过方式表进行对比,得出当前挑战的官位(例:41血完成拾肆段,血量残余82%,则为紫袍拾肆通过)。 - 以下是通过方式: - - 黄袍 x=100% - - 紫袍 100%>x≥80% - - 红袍 80%>x≥55% - - 绿袍 55%>x≥30% - - 青袍 30%>x>0% - - 布衣(失败) x≤0% + **Dan rules** + Challenge fails if HP reaches 0 during the challenge. \ + The HP reduces by 1 when one judgement that is or is below the hit-by judgement apppears. \ + The HP heals at the end of each level within the dan course (except the last one). \ + You need to pass four songs in a row without retrying to pass a dan course. \ + If there are two sets of songs in a dan course, you can choose either one to pass. \ + Calculate the ratio `x` of the remaining HP to the initial HP, and compare it with the following table to get your dan rank: + - Yellow: `x = 100%`; + - Purple: `100% > x >= 80%`; + - Red: `80% > x >= 55%`; + - Green: `55% > x >= 30%`; + - Blue: `30% > x > 0%`; + - White (fail): `x <= 0%`. INFO }[item.to_sym] || 'Unknown item.' end @@ -561,6 +568,22 @@ def b15 lang, session_token "**Username**\t#{user[:username]}\n**Created at**\t#{user[:created_at]}\n**Nickname**\t#{user[:nickname]}" end + description = <<~DESC.gsub ?\n, ?\s + Display basic information about a dan. + The dan ID ranges from 1 to 18. + Including the levels, hit points, healing, and hit-by judgement. + Append `dan` with one of `tw`, `cn`, `jp`, `eng` (such as `dancn`) + to specify the language. + DESC + usage = 'dan[lang] [dan ID]' + gen_multilingual_commands :dan, description:, usage:, min_args: 1, max_args: 1 do |lang, dan_id| + return '*Bad dan ID.*' unless dan_id.like_int? + dan_id = dan_id.to_i + dan = Dan::LIB[dan_id] + return '*No such dan.*' unless dan + dan.info_inspect lang + end + end end diff --git a/lib/lyricat/dan.rb b/lib/lyricat/dan.rb new file mode 100644 index 0000000..0bcd2ea --- /dev/null +++ b/lib/lyricat/dan.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Lyricat + class Dan + + lang_sheet = Lyricat.sheet :language + begin item = lang_sheet.shift end until item[:index] == '#' && item[:tw] == 1 + JUDGEMENT_NAMES = (0..3).map { [_1, lang_sheet[14+_1]] }.to_h.freeze + + attr_reader :index, :levels, :health, :heal, :judgement + + def initialize hash + @index = hash[:index] + @levels = hash[:levels] + @health = hash[:health] + @heal = hash[:heal] + @judgement = hash[:judgement] + end + + def info_inspect lang + levels = @levels.map do |bunch| + bunch.map.with_index do |level, i| + song = Song::LIB[level[:song_id]] + diff_id = level[:diff_id] + diff_name = Song::DIFFS_NAME[diff_id][lang] + diff = song.diff(lang, :in_game_and_abbr_precise)[diff_id] + "#{i+1}. #{song.name lang}\t#{diff_name} #{diff}" + end.join ?\n + end + <<~END + **Dan**\t#{@index} + **Levels** + #{levels.join "\nOR\n"} + **Hit points**\t#{@health} + **Healing**\t#{@heal} + **Hit by**\t#{JUDGEMENT_NAMES[@judgement][lang]} + END + end + + LIB = YAML.load_file(File.join(Lyricat::DATA_DIR, ENV['LYRICAT_DAN'] || 'dan.yml'), symbolize_names: true).map { [_1[:index], new(_1)] }.to_h.freeze + end +end diff --git a/lib/lyricat/version.rb b/lib/lyricat/version.rb index 81d6c96..6714694 100644 --- a/lib/lyricat/version.rb +++ b/lib/lyricat/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Lyricat - VERSION = '0.2.0' + VERSION = '0.3.0' end