bcdice 3.6.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -0
- data/i18n/Arianrhod/ja_jp.yml +3 -0
- data/i18n/Emoklore/ja_jp.yml +7 -0
- data/i18n/FutariSousa/ja_jp.yml +431 -0
- data/i18n/LogHorizon/ja_jp.yml +1 -1
- data/i18n/SwordWorld/ja_jp.yml +1 -0
- data/i18n/SwordWorld/zh_hans.yml +7 -0
- data/i18n/SwordWorld2_0/zh_hans.yml +37 -0
- data/i18n/SwordWorld2_5/ja_jp.yml +1 -1
- data/i18n/SwordWorld2_5/zh_hans.yml +57 -0
- data/lib/bcdice/arithmetic/parser.rb +1 -1
- data/lib/bcdice/command/parser.rb +1 -1
- data/lib/bcdice/common_command/add_dice/parser.rb +106 -74
- data/lib/bcdice/common_command/add_dice.rb +1 -1
- data/lib/bcdice/common_command/barabara_dice/parser.rb +1 -1
- data/lib/bcdice/common_command/calc/parser.rb +1 -1
- data/lib/bcdice/common_command/d66_dice.rb +1 -1
- data/lib/bcdice/common_command/reroll_dice/parser.rb +1 -1
- data/lib/bcdice/common_command/tally_dice/parser.rb +1 -1
- data/lib/bcdice/common_command/upper_dice/parser.rb +1 -1
- data/lib/bcdice/game_system/AngelGear.rb +1 -1
- data/lib/bcdice/game_system/AnimaAnimus.rb +1 -1
- data/lib/bcdice/game_system/Arianrhod.rb +4 -4
- data/lib/bcdice/game_system/AssaultEngine.rb +3 -3
- data/lib/bcdice/game_system/Ayabito.rb +170 -4
- data/lib/bcdice/game_system/BeastBindTrinity.rb +1 -1
- data/lib/bcdice/game_system/BeginningIdol.rb +4 -2
- data/lib/bcdice/game_system/BeginningIdol2022.rb +184 -0
- data/lib/bcdice/game_system/BladeOfArcana.rb +3 -3
- data/lib/bcdice/game_system/Bloodorium.rb +68 -0
- data/lib/bcdice/game_system/ConvictorDrive.rb +117 -0
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
- data/lib/bcdice/game_system/CyberpunkRed.rb +2 -6
- data/lib/bcdice/game_system/DeadlineHeroes.rb +1 -1
- data/lib/bcdice/game_system/DungeonsAndDragons5.rb +196 -0
- data/lib/bcdice/game_system/EmbryoMachine.rb +4 -4
- data/lib/bcdice/game_system/Emoklore.rb +8 -8
- data/lib/bcdice/game_system/FutariSousa.rb +31 -5
- data/lib/bcdice/game_system/GURPS.rb +1 -1
- data/lib/bcdice/game_system/GehennaAn.rb +2 -2
- data/lib/bcdice/game_system/GhostLive.rb +144 -0
- data/lib/bcdice/game_system/GoblinSlayer.rb +30 -8
- data/lib/bcdice/game_system/HunterTheReckoning5th.rb +152 -0
- data/lib/bcdice/game_system/IfIfIf.rb +648 -0
- data/lib/bcdice/game_system/Kutulu.rb +95 -0
- data/lib/bcdice/game_system/LostRoyal.rb +1 -1
- data/lib/bcdice/game_system/NobunagasBlackCastle.rb +237 -0
- data/lib/bcdice/game_system/OracleEngine.rb +1 -1
- data/lib/bcdice/game_system/Raisondetre.rb +1 -1
- data/lib/bcdice/game_system/RokumonSekai2.rb +1 -1
- data/lib/bcdice/game_system/SajinsenkiAGuS.rb +154 -0
- data/lib/bcdice/game_system/Sengensyou.rb +59 -0
- data/lib/bcdice/game_system/ShinkuuGakuen.rb +1 -1
- data/lib/bcdice/game_system/ShinobiGami.rb +14 -1
- data/lib/bcdice/game_system/SkynautsBouken.rb +93 -2
- data/lib/bcdice/game_system/StellarLife.rb +1 -1
- data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +2 -2
- data/lib/bcdice/game_system/SwordWorld2_0_SimplifiedChinese.rb +84 -0
- data/lib/bcdice/game_system/SwordWorld2_5_SimplifiedChinese.rb +95 -0
- data/lib/bcdice/game_system/SwordWorld_SimplifiedChinese.rb +29 -0
- data/lib/bcdice/game_system/TherapieSein.rb +2 -2
- data/lib/bcdice/game_system/Torg.rb +1 -1
- data/lib/bcdice/game_system/TorgEternity.rb +54 -18
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +26 -12
- data/lib/bcdice/game_system/VisionConnect.rb +135 -0
- data/lib/bcdice/game_system/Warhammer4.rb +4 -0
- data/lib/bcdice/game_system/WorldOfDarkness.rb +54 -50
- data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +1 -1
- data/lib/bcdice/game_system/filled_with/tresure_tables.rb +1 -1
- data/lib/bcdice/game_system/satasupe/tables.rb +1 -1
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +1 -1
- data/lib/bcdice/game_system.rb +15 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +26 -6
@@ -15,10 +15,11 @@ module BCDice
|
|
15
15
|
SORT_KEY = "あやひと"
|
16
16
|
|
17
17
|
HELP_MESSAGE = <<~TEXT
|
18
|
-
・判定コマンド(xAB±y@c>=z)
|
18
|
+
・判定コマンド(xAB±y@c$d>=z)
|
19
19
|
x:サイコロの数(10以上の場合9個振り、それ以降を成功数2として加算する)
|
20
20
|
±y:成功数への補正(省略可)
|
21
21
|
c:クリティカル値(@ごと省略可。省略時は6)
|
22
|
+
d:出目を2として数える数の最小値($ごと省略可。省略時は6)
|
22
23
|
z:目標値(妨害値など。>=ごと省略可)
|
23
24
|
(例) 4AB
|
24
25
|
11AB>=5
|
@@ -31,6 +32,14 @@ module BCDice
|
|
31
32
|
交流表 CET
|
32
33
|
ファンブル表 FT
|
33
34
|
封印期間表 LT
|
35
|
+
|
36
|
+
帝都東京エリア選択 TET
|
37
|
+
浅草シーン表 AST
|
38
|
+
上野シーン表 UST
|
39
|
+
日本橋シーン表 NST
|
40
|
+
銀座シーン表 GST
|
41
|
+
霞ヶ関シーン表 KST
|
42
|
+
新宿シーン表 SST
|
34
43
|
TEXT
|
35
44
|
|
36
45
|
def initialize(command)
|
@@ -44,7 +53,7 @@ module BCDice
|
|
44
53
|
end
|
45
54
|
|
46
55
|
def check_action(command)
|
47
|
-
parser = Command::Parser.new("AB", round_type: RoundType::CEIL).has_prefix_number.enable_critical.restrict_cmp_op_to(nil, :>=)
|
56
|
+
parser = Command::Parser.new("AB", round_type: RoundType::CEIL).has_prefix_number.enable_critical.enable_dollar.restrict_cmp_op_to(nil, :>=)
|
48
57
|
parsed = parser.parse(command)
|
49
58
|
return nil if parsed.nil?
|
50
59
|
|
@@ -57,19 +66,20 @@ module BCDice
|
|
57
66
|
end
|
58
67
|
modify = parsed.modify_number
|
59
68
|
critical_target = parsed.critical || 6
|
69
|
+
addition_target = parsed.dollar || 6
|
60
70
|
target = parsed.target_number
|
61
71
|
|
62
72
|
dice_arr = @randomizer.roll_barabara(dice_cnt, 6).sort
|
63
73
|
dice_str = dice_arr.join(",")
|
64
74
|
has_critical = dice_arr.any? { |x| x >= critical_target }
|
65
|
-
success_cnt = dice_arr.count { |x| x >= 4 } + dice_arr.count
|
75
|
+
success_cnt = dice_arr.count { |x| x >= 4 } + dice_arr.count { |x| x >= addition_target } + over_modify * 2
|
66
76
|
has_fumble = success_cnt == 0 && dice_arr.include?(1)
|
67
77
|
if has_fumble
|
68
78
|
success_cnt = 0
|
69
79
|
else
|
70
80
|
success_cnt += modify
|
71
81
|
end
|
72
|
-
result = target.nil? ? success_cnt >= 1 : success_cnt
|
82
|
+
result = target.nil? ? success_cnt >= 1 : success_cnt >= target
|
73
83
|
|
74
84
|
Result.new.tap do |r|
|
75
85
|
r.text = "(#{dice_cnt}B6>=4)#{over_modify > 0 ? "+#{over_modify * 2}" : ''} > [#{dice_str}]#{over_modify > 0 ? "+#{over_modify * 2}" : ''} > 成功数#{success_cnt} > #{result ? '成功' : '失敗'}#{has_critical ? '(クリティカル)' : ''}#{has_fumble ? '(ファンブル)' : ''}"
|
@@ -221,6 +231,162 @@ module BCDice
|
|
221
231
|
# '500年',
|
222
232
|
]
|
223
233
|
),
|
234
|
+
'TET' => DiceTable::Table.new(
|
235
|
+
'帝都東京エリア選択',
|
236
|
+
'1D6',
|
237
|
+
[
|
238
|
+
'浅草。庶民の盛り場として賑わう商店街と下町。',
|
239
|
+
'上野。あらゆる路線の中心である帝都の玄関口。',
|
240
|
+
'日本橋。江戸時代から変わらぬ商業の中心地。',
|
241
|
+
'銀座。赤煉瓦が立ち並ぶ、帝都一モダンな繁華街。',
|
242
|
+
'霞ヶ関。国会議事堂や裁判所がある官庁街。',
|
243
|
+
'新宿。関東大震災以降、急速に発展した新しい街。',
|
244
|
+
]
|
245
|
+
),
|
246
|
+
'AST' => DiceTable::D66LeftRangeTable.new(
|
247
|
+
'浅草シーン表',
|
248
|
+
D66SortType::NO_SORT,
|
249
|
+
[
|
250
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
251
|
+
[2..3, [
|
252
|
+
"[子]浅草寺。浅草の顔ともいえる寺。7世紀に建造された都内でも最古の寺。",
|
253
|
+
"[丑]武神一刀流道場。浅草でも有名な剣術道場。柔術や薙刀など、剣以外の実践的な技も教えている。",
|
254
|
+
"[寅]待乳の渡し。隅田川を橋で渡る代わりに、乗せて渡ってくれる小舟。",
|
255
|
+
"[卯]帝都観光案内館。帝都東京内観光の案内所。ガイドつきのバス観光も行っている。",
|
256
|
+
"[辰]神谷バー。老舗の飲食店であり、電気ブランを提供していることで有名。",
|
257
|
+
"[巳]雷門。浅草寺の南側に建てられた門で、風神と雷神の像が安置されている。",
|
258
|
+
]],
|
259
|
+
[4..5, [
|
260
|
+
"[午]仲見世。雷門から浅草寺本堂に続く仁王門まで立ち並ぶ商店街。",
|
261
|
+
"[未]仰天堂。やたらと大盛りの食事を提供してくれる人気店。",
|
262
|
+
"[申]混沌興行。妖怪たちが演じることで有名な見世物小屋。いつも混み合っている。",
|
263
|
+
"[酉]浅草六区。浅草の中心街であり、店舗や演芸場、活動写真館が並んでいる。",
|
264
|
+
"[戌]凌雲閣。浅草十二階とも呼ばれる塔。関東大震災でも崩れることなく、そびえ立っている。",
|
265
|
+
"[亥]花屋敷。日本最初の遊園地であり、園内には動物園も完備している。",
|
266
|
+
]],
|
267
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
268
|
+
]
|
269
|
+
),
|
270
|
+
'UST' => DiceTable::D66LeftRangeTable.new(
|
271
|
+
'上野シーン表',
|
272
|
+
D66SortType::NO_SORT,
|
273
|
+
[
|
274
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
275
|
+
[2..3, [
|
276
|
+
"[子]上野恩賜公園。桜の名所でもある巨大な公園。敷地内では、四季折々の自然を楽しむことができる。",
|
277
|
+
"[丑]東京帝室博物館。宮内省所管の博物館であり、珍しい品々が展示されている。",
|
278
|
+
"[寅]上野駅。帝都と地方の路線を繋ぐ駅。地方から上京してくる人々を多く見かける。",
|
279
|
+
"[卯]精養軒。本格的な洋食が楽しめる老舗のレストラン。人間、妖怪に限らず上流階級が通っている。",
|
280
|
+
"[辰]御徒町。高架下と周辺に所狭しと民家や長屋、様々な店がひしめきあう下町の歓楽街。",
|
281
|
+
"[巳]一鉄工場。偏屈で頑固だが有能な老人が経営する工場。自作のラジオが置かれている。",
|
282
|
+
]],
|
283
|
+
[4..5, [
|
284
|
+
"[午]帝国大学。象徴の赤門が有名な、日本の最高学府。校内には、妖怪研究室がある。",
|
285
|
+
"[未]鳳明館。明治創業の旅館。文士が執筆する際に、よく利用している。",
|
286
|
+
"[申]黄龍門学園。帝国大学敷地の横にある私立学園。妖怪や半妖も多く通っている。",
|
287
|
+
"[酉]不忍池。弁天堂と大黒天堂を構える池で、河童が隠れ住んでいる。",
|
288
|
+
"[戌]きさらぎ長屋。行く宛のない者や、行き場をなくした者が集まる長屋。",
|
289
|
+
"[亥]上野恩賜公園動物園。ホッキョクグマ舎やサル山をはじめ、珍しい動物が飼われている。",
|
290
|
+
]],
|
291
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
292
|
+
]
|
293
|
+
),
|
294
|
+
'NST' => DiceTable::D66LeftRangeTable.new(
|
295
|
+
'日本橋シーン表',
|
296
|
+
D66SortType::NO_SORT,
|
297
|
+
[
|
298
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
299
|
+
[2..3, [
|
300
|
+
"[子]日本銀行本店。西洋建築の先駆けといえる建築物。帝都事変では大きな被害が出た。",
|
301
|
+
"[丑]三越。日本橋に居を構える有数の大型百貨店。この店で揃わぬ物はないとされている。",
|
302
|
+
"[寅]日本橋。五つ街道の起点であり、東海道五十三次の出発点としてよく知られる橋。",
|
303
|
+
"[卯]メイゾン妖の巣。妖怪や半妖の文学者たちが集うカフェー。",
|
304
|
+
"[辰]大正座。明治座の兄弟とよばれる演芸場。歌舞伎や芝居などが上演されている。",
|
305
|
+
"[巳]多々良堂。江戸時代より続く退魔具の専門店。多くのあやびとが訪れる。",
|
306
|
+
]],
|
307
|
+
[4..5, [
|
308
|
+
"[午]妖艶大世界。上海にある上海大世界を真似て、妖怪や半妖が集まってできた新興の花街。",
|
309
|
+
"[未]二丁巴里。丸ノ内の一丁倫敦に対して創られた大規模な問屋街。",
|
310
|
+
"[申]皇居外苑。桔梗門の前は大広場があり、皇居を訪れる者が集まっている。",
|
311
|
+
"[酉]東京駅。皇居に対面する形で作られた煉瓦造りの壮麗な駅。",
|
312
|
+
"[戌]丸ノ内ビルヂング。大正12年に竣工した東洋一ともいわれる巨大なビルヂング。",
|
313
|
+
"[亥]将門塚。平将門公の御首が祀られる塚。大手町にひっそりと存在している。",
|
314
|
+
]],
|
315
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
316
|
+
]
|
317
|
+
),
|
318
|
+
'GST' => DiceTable::D66LeftRangeTable.new(
|
319
|
+
'銀座シーン表',
|
320
|
+
D66SortType::NO_SORT,
|
321
|
+
[
|
322
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
323
|
+
[2..3, [
|
324
|
+
"[子]ダンスホウル・ガアデン。モダンボーイやモダンガール御用達の帝都東京有数のダンスホウル。",
|
325
|
+
"[丑]服部時計店。銀座のシンボルとなっている時計塔と、併設された店舗。",
|
326
|
+
"[寅]松屋。大正14年に開店した百貨店。地上7階までの吹き抜けステンドグラスで知られる。",
|
327
|
+
"[卯]歌舞伎座。歌舞伎の殿堂。古式ゆかしい意匠を取り入れた最新建築の劇場。",
|
328
|
+
"[辰]倫敦橋。文士や芸術家が好んで訪れる2階建ての洋式建築のカフェー。",
|
329
|
+
"[巳]資生堂パーラー。ソーダ水やアイスクリンを提供したことで有名な喫茶店。",
|
330
|
+
]],
|
331
|
+
[4..5, [
|
332
|
+
"[午]カフェープランタン。日本初のカフェーといわれる老舗。富裕層やインテリ層が多く訪れる。",
|
333
|
+
"[未]新橋絢爛花街。関東大震災をきっかけに再建された花街。政府高官なども利用している。",
|
334
|
+
"[申]鹿鳴館。明治時代を代表する西洋建築。華族や資産家が利用できる施設となっている。",
|
335
|
+
"[酉]帝国ホテル。フランク・ロイド・ライトが設計した最新鋭の技術が詰め込まれたホテル。",
|
336
|
+
"[戌]妖務省本部。妖務省と妖怪人間共同実働部隊の本部が置かれている。",
|
337
|
+
"[亥]帝国劇場。明治時代を代表する日本最大の大劇場で\"帝劇\"の愛称で知られている。",
|
338
|
+
]],
|
339
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
340
|
+
]
|
341
|
+
),
|
342
|
+
'KST' => DiceTable::D66LeftRangeTable.new(
|
343
|
+
'霞ヶ関シーン表',
|
344
|
+
D66SortType::NO_SORT,
|
345
|
+
[
|
346
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
347
|
+
[2..3, [
|
348
|
+
"[子]桜田門。内堀にある門のひとつで皇居に通じている。",
|
349
|
+
"[丑]警視庁庁舎。警視庁の総合本部。庁舎内に妖鬼対策本部がある。",
|
350
|
+
"[寅]日比谷公園。市民の憩いの場所であり、図書館や音楽堂をそなえる大規模な公園。",
|
351
|
+
"[卯]大審院庁舎。司法裁判所の中における最上級審の裁判所。",
|
352
|
+
"[辰]私立聖ロザリオ女学園。愛宕山の森に囲まれた都内随一のお嬢様学校。",
|
353
|
+
"[巳]片倉組。武家屋敷を改装した本邸であり、帝都屈指のヤクザの根城となっている。",
|
354
|
+
]],
|
355
|
+
[4..5, [
|
356
|
+
"[午]妖人史料編纂局。妖怪の史料の収集と編纂を目的として設置された官立組織。",
|
357
|
+
"[未]鰐淵金融。利子こそ高いが、誰にでも門戸を開いている貸金業者。",
|
358
|
+
"[申]料亭山王園。政治家や官僚御用達の料亭。十二真鬼も出入りしている。",
|
359
|
+
"[酉]日枝神社。山王祭で知られる神社。数多くの刀剣が納められている。",
|
360
|
+
"[戌]国会議事堂。現在建設中の国会議事堂。大正25年に竣工予定で、現在は木造の仮議事堂がある。",
|
361
|
+
"[亥]帝国図書館。国立図書館で、国内で出版されたあらゆる書籍が収蔵されている。",
|
362
|
+
]],
|
363
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
364
|
+
]
|
365
|
+
),
|
366
|
+
'SST' => DiceTable::D66LeftRangeTable.new(
|
367
|
+
'新宿シーン表',
|
368
|
+
D66SortType::NO_SORT,
|
369
|
+
[
|
370
|
+
[1..1, Array.new(6, "子~巳までの任意の十二支を選択する。")],
|
371
|
+
[2..3, [
|
372
|
+
"[子]武蔵野館。座席数1,200を誇る国内有数の活動大写真館。",
|
373
|
+
"[丑]二幸。食料品専門百貨店。あやびとたちに友好的で、伝奇事件が解決すると飲食が提供される。",
|
374
|
+
"[寅]高野フルーツパーラー。マスクメロンが有名な果物専門店と、併設された果物が楽しめる飲食店。",
|
375
|
+
"[卯]紀伊國屋書店。大正16年に創業した、文士たちが集うサロンのような大型書店。",
|
376
|
+
"[辰]新宿御苑。宮内省が管理する皇室のための庭園。封印具の保管庫である浄玻璃ノ宮がある。",
|
377
|
+
"[巳]明治神宮。明治天皇と昭憲皇太后を祭神とした神社。境内は厳かな雰囲気に満ちている。",
|
378
|
+
]],
|
379
|
+
[4..5, [
|
380
|
+
"[午]新宿駅。多摩や小田原からの玄関口となる駅。1日あたりの乗降客数は日本一。",
|
381
|
+
"[未]酩酊横丁。長屋が連なる路地に、200軒以上もの居酒屋やバーがひしめいている。",
|
382
|
+
"[申]歌楽騒戯通り。関東大震災後に作られた真新しい建物がひしめく歓楽街。",
|
383
|
+
"[酉]淀橋浄水場。コレラ流行後に、水道を近代化させるために作られた浄水場。",
|
384
|
+
"[戌]新宿大通り。急速な発展を遂げた新宿のメイン通り。",
|
385
|
+
"[亥]ほたる屋。妖狐と妖狸が経営している衣料品専門の百貨店。",
|
386
|
+
]],
|
387
|
+
[6..6, Array.new(6, "午~亥まで任意の十二支を選択する。")],
|
388
|
+
]
|
389
|
+
),
|
224
390
|
}.freeze
|
225
391
|
|
226
392
|
register_prefix('\d*AB', TABLES.keys)
|
@@ -115,7 +115,7 @@ module BCDice
|
|
115
115
|
private
|
116
116
|
|
117
117
|
def parse()
|
118
|
-
m = /^(\d+)(?:R6|BB6?)((?:[
|
118
|
+
m = /^(\d+)(?:R6|BB6?)((?:[+-]\d+)+)?(?:%(-?\d+))?(?:@([+\-\d]+))?(?:#(A)?([+\-\d]+))?(?:\$([1-6]+))?(?:&([1-6]))?(?:([>=]+)(\d+))?$/.match(@command)
|
119
119
|
unless m
|
120
120
|
@parse_error = true
|
121
121
|
return
|
@@ -16,6 +16,8 @@ module BCDice
|
|
16
16
|
|
17
17
|
# ダイスボットの使い方
|
18
18
|
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
19
|
+
これは、2015年に新書サイズで発売された『駆け出しアイドルRPG ビギニングアイドル チャレンジガールズ』およびそのサプリメントに対応したコマンドです。
|
20
|
+
|
19
21
|
・パフォーマンス [r]PDn[+m/-m](r:場に残った出目 n:振る数 m:修正値)
|
20
22
|
・ワールドセッティング仕事表 BWT:大手芸能プロ LWT:弱小芸能プロ
|
21
23
|
TWT:ライブシアター CWT:アイドル部 LO[n]:地方アイドル(n:チャンス)
|
@@ -143,7 +145,7 @@ module BCDice
|
|
143
145
|
end
|
144
146
|
|
145
147
|
def roll_attack(command)
|
146
|
-
m = /^(\d+)(S?)A([1-6]*)([
|
148
|
+
m = /^(\d+)(S?)A([1-6]*)([+-]\d+)?$/.match(command)
|
147
149
|
unless m
|
148
150
|
return nil
|
149
151
|
end
|
@@ -177,7 +179,7 @@ module BCDice
|
|
177
179
|
end
|
178
180
|
|
179
181
|
def roll_performance(command)
|
180
|
-
m = /^([1-7]*)PD(\d+)([
|
182
|
+
m = /^([1-7]*)PD(\d+)([+-]\d+)?$/.match(command)
|
181
183
|
unless m
|
182
184
|
return nil
|
183
185
|
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class BeginningIdol2022 < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'BeginningIdol2022'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = 'ビギニングアイドル(2022年改訂版)'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'ひきにんくあいとる2022'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
17
|
+
これは、2022年に大判サイズで発売された『駆け出しアイドルRPG ビギニングアイドル 基本ルールブック』に対応したコマンドです。
|
18
|
+
|
19
|
+
・行為判定 BIn@c#f+m>=t
|
20
|
+
nD6をダイスロールし、行為判定に成功したかを出力します。スペシャルとファンブルの判定も行います。
|
21
|
+
n: ダイス数(省略時 2)
|
22
|
+
c: スペシャル値(省略時 12)
|
23
|
+
f: ファンブル値(省略時 2)
|
24
|
+
m: 修正値(省略可)
|
25
|
+
t: 目標値
|
26
|
+
|
27
|
+
・パフォーマンス判定 PDn+m
|
28
|
+
nD6をダイスロールし、パフォーマンス値を出力します。パーフェクトミラクルとミラクルの判定も行います。
|
29
|
+
n: ダイス数
|
30
|
+
m: 修正値(省略可)
|
31
|
+
|
32
|
+
・シンフォニー xxxPDn+m
|
33
|
+
nD6をダイスロールし、場に残っているダイスを加味してパフォーマンス値を出力します。
|
34
|
+
パーフェクトミラクルとミラクルシンクロの判定も行います。
|
35
|
+
xxx: 場に残っているダイスの出目を列挙したもの
|
36
|
+
n: ダイス数
|
37
|
+
m: 修正値(省略可)
|
38
|
+
INFO_MESSAGE_TEXT
|
39
|
+
|
40
|
+
def initialize(command)
|
41
|
+
super(command)
|
42
|
+
|
43
|
+
@sort_add_dice = true
|
44
|
+
@d66_sort_type = D66SortType::ASC
|
45
|
+
end
|
46
|
+
|
47
|
+
register_prefix("BI", "PD", "[1-6]+PD")
|
48
|
+
|
49
|
+
def eval_game_system_specific_command(command)
|
50
|
+
roll_skill_check(command) || roll_performance_check(command) || roll_symphony_check(command)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# 行為判定
|
56
|
+
def roll_skill_check(command)
|
57
|
+
parser = Command::Parser.new("BI", round_type: @round_type)
|
58
|
+
.enable_suffix_number
|
59
|
+
.enable_critical
|
60
|
+
.enable_fumble
|
61
|
+
.restrict_cmp_op_to(:>=)
|
62
|
+
parsed = parser.parse(command)
|
63
|
+
unless parsed
|
64
|
+
return nil
|
65
|
+
end
|
66
|
+
|
67
|
+
dice_times = parsed.suffix_number || 2
|
68
|
+
critical = parsed.critical || 12
|
69
|
+
fumble = parsed.fumble || 2
|
70
|
+
|
71
|
+
dice_list = @randomizer.roll_barabara(dice_times, 6).sort()
|
72
|
+
dice_total = dice_list.sum()
|
73
|
+
is_critical = dice_total >= critical
|
74
|
+
is_fumble = !is_critical && dice_total <= fumble
|
75
|
+
total = dice_total + parsed.modify_number
|
76
|
+
|
77
|
+
result =
|
78
|
+
if is_critical
|
79
|
+
Result.critical("スペシャル(PCは【思い出】を1つ獲得する)")
|
80
|
+
elsif is_fumble
|
81
|
+
Result.fumble("ファンブル(【思い出】を1つ獲得し、ファンブル表を振る)")
|
82
|
+
elsif total >= parsed.target_number
|
83
|
+
Result.success("成功")
|
84
|
+
else
|
85
|
+
Result.failure("失敗")
|
86
|
+
end
|
87
|
+
|
88
|
+
result.text = "(#{parsed}) > #{dice_total}[#{dice_list.join(',')}]#{Format.modifier(parsed.modify_number)} > #{total} > #{result.text}"
|
89
|
+
return result
|
90
|
+
end
|
91
|
+
|
92
|
+
# パフォーマンス判定
|
93
|
+
def roll_performance_check(command)
|
94
|
+
m = /^PD(\d+)([+-]\d+)?$/.match(command)
|
95
|
+
unless m
|
96
|
+
return nil
|
97
|
+
end
|
98
|
+
|
99
|
+
suffix_number = m[1].to_i
|
100
|
+
modifier = m[2].to_i
|
101
|
+
is_extension = suffix_number >= 7
|
102
|
+
dice_times = is_extension ? 6 : suffix_number
|
103
|
+
extension_bonus = is_extension ? suffix_number - dice_times : 0
|
104
|
+
|
105
|
+
if dice_times <= 0
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
|
109
|
+
dice_list = @randomizer.roll_barabara(dice_times, 6).sort()
|
110
|
+
uniqed = select_uniqs(dice_list).sort()
|
111
|
+
|
112
|
+
is_perfect_miracle = uniqed == [1, 2, 3, 4, 5, 6]
|
113
|
+
is_miracle = uniqed.empty?
|
114
|
+
result_label =
|
115
|
+
if is_perfect_miracle
|
116
|
+
"【パーフェクトミラクル】#{30 + extension_bonus + modifier}"
|
117
|
+
elsif is_miracle
|
118
|
+
"【ミラクル】#{10 + extension_bonus + modifier}"
|
119
|
+
else
|
120
|
+
(uniqed.sum() + extension_bonus + modifier).to_s
|
121
|
+
end
|
122
|
+
if is_extension
|
123
|
+
result_label += " (エクステンション: #{extension_bonus}個まで振りなおし可能)"
|
124
|
+
end
|
125
|
+
|
126
|
+
Result.new.tap do |result|
|
127
|
+
result.critical = is_perfect_miracle || is_miracle
|
128
|
+
result.text = [
|
129
|
+
"(#{command})",
|
130
|
+
"パフォーマンス判定",
|
131
|
+
"[#{dice_list.join(',')}]#{Format.modifier(extension_bonus)}#{Format.modifier(modifier)}",
|
132
|
+
("[#{uniqed.join(',')}]#{Format.modifier(extension_bonus)}#{Format.modifier(modifier)}" if dice_list.size != uniqed.size),
|
133
|
+
result_label,
|
134
|
+
].compact.join(" > ")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def select_uniqs(array)
|
139
|
+
# TODO: Ruby 2.7以降のみサポートするようになった場合に Enumerable#tally で書く
|
140
|
+
array.group_by(&:itself)
|
141
|
+
.to_a
|
142
|
+
.select { |_, arr| arr.size == 1 }
|
143
|
+
.map { |key, _| key }
|
144
|
+
end
|
145
|
+
|
146
|
+
# シンフォニー
|
147
|
+
def roll_symphony_check(command)
|
148
|
+
m = /^([1-6]+)PD([1-6])([+-]\d+)?$/.match(command)
|
149
|
+
unless m
|
150
|
+
return nil
|
151
|
+
end
|
152
|
+
|
153
|
+
carries = m[1].chars.map(&:to_i).sort()
|
154
|
+
dice_times = m[2].to_i
|
155
|
+
modifier = m[3].to_i
|
156
|
+
|
157
|
+
dice_list = @randomizer.roll_barabara(dice_times, 6).sort()
|
158
|
+
uniqed = select_uniqs(carries + dice_list).sort()
|
159
|
+
|
160
|
+
is_perfect_miracle = uniqed == [1, 2, 3, 4, 5, 6]
|
161
|
+
is_miracle_synchro = uniqed.empty?
|
162
|
+
result_label =
|
163
|
+
if is_perfect_miracle
|
164
|
+
"【パーフェクトミラクル】#{30 + modifier}"
|
165
|
+
elsif is_miracle_synchro
|
166
|
+
"【ミラクルシンクロ】#{20 + modifier}"
|
167
|
+
else
|
168
|
+
(uniqed.sum() + modifier).to_s
|
169
|
+
end
|
170
|
+
|
171
|
+
Result.new.tap do |result|
|
172
|
+
result.critical = is_perfect_miracle || is_miracle_synchro
|
173
|
+
result.text = [
|
174
|
+
"(#{command})",
|
175
|
+
"シンフォニー",
|
176
|
+
"[#{carries.join(',')}],[#{dice_list.join(',')}]#{Format.modifier(modifier)}",
|
177
|
+
"[#{uniqed.join(',')}]#{Format.modifier(modifier)}",
|
178
|
+
result_label,
|
179
|
+
].join(" > ")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -66,7 +66,7 @@ module BCDice
|
|
66
66
|
end
|
67
67
|
return rollAct(counts, judgment, critical, fumble)
|
68
68
|
|
69
|
-
when /^CT3([
|
69
|
+
when /^CT3([+-]?)$/
|
70
70
|
sign = Regexp.last_match(1)
|
71
71
|
title = '因縁表(The 3rd) 『BoA3』P292'
|
72
72
|
table = [
|
@@ -95,7 +95,7 @@ module BCDice
|
|
95
95
|
]
|
96
96
|
return tableText(title, table, sign)
|
97
97
|
|
98
|
-
when /^CTR([
|
98
|
+
when /^CTR([+-]?)$/
|
99
99
|
sign = Regexp.last_match(1)
|
100
100
|
title = '因縁表(リインカーネイション) 『BAR』P51、299'
|
101
101
|
table = [
|
@@ -153,7 +153,7 @@ module BCDice
|
|
153
153
|
]
|
154
154
|
return tableText(title, table, sign)
|
155
155
|
|
156
|
-
when /^AKST([
|
156
|
+
when /^AKST([+-]?)$/
|
157
157
|
sign = Regexp.last_match(1)
|
158
158
|
title = '悪徳シーン表 『GoV』P16、164'
|
159
159
|
table = [
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Bloodorium < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'Bloodorium'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = 'ブラドリウム'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'ふらとりうむ'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
17
|
+
・ダイスチェック xDC+y
|
18
|
+
【ダイスチェック】を行う。《トライアンフ》を結果に自動反映する。
|
19
|
+
x: ダイス数
|
20
|
+
y: 結果への修正値 (省略可)
|
21
|
+
INFO_MESSAGE_TEXT
|
22
|
+
|
23
|
+
register_prefix('\dDC')
|
24
|
+
|
25
|
+
def eval_game_system_specific_command(command)
|
26
|
+
dicecheck(command)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def dicecheck(command)
|
32
|
+
parser = Command::Parser.new("DC", round_type: @round_type).has_prefix_number.restrict_cmp_op_to(nil)
|
33
|
+
parsed = parser.parse(command)
|
34
|
+
unless parsed
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
|
38
|
+
dice_list = @randomizer.roll_barabara(parsed.prefix_number, 6).sort
|
39
|
+
dice_value = dice_list.max
|
40
|
+
values_count = dice_list
|
41
|
+
.group_by(&:itself)
|
42
|
+
.transform_values(&:length)
|
43
|
+
triumph = values_count.values.max
|
44
|
+
|
45
|
+
total = dice_value * triumph + parsed.modify_number
|
46
|
+
|
47
|
+
sequence = [
|
48
|
+
"(#{parsed})",
|
49
|
+
"[#{dice_list.join(',')}]#{Format.modifier(parsed.modify_number)}",
|
50
|
+
("《トライアンフ》(*#{triumph})" if triumph > 1),
|
51
|
+
(total_expr(dice_value, triumph, parsed.modify_number) if total != dice_value),
|
52
|
+
total,
|
53
|
+
].compact
|
54
|
+
|
55
|
+
return Result.new.tap do |r|
|
56
|
+
r.critical = triumph > 1
|
57
|
+
r.text = sequence.join(" > ")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def total_expr(dice_value, triumph, modify_number)
|
62
|
+
formated_triumph = triumph > 1 ? "*#{triumph}" : nil
|
63
|
+
|
64
|
+
return "#{dice_value}#{formated_triumph}#{Format.modifier(modify_number)}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bcdice/base'
|
4
|
+
|
5
|
+
module BCDice
|
6
|
+
module GameSystem
|
7
|
+
class ConvictorDrive < Base
|
8
|
+
# ゲームシステムの識別子
|
9
|
+
ID = 'ConvictorDrive'
|
10
|
+
|
11
|
+
# ゲームシステム名
|
12
|
+
NAME = 'コンヴィクター・ドライブ'
|
13
|
+
|
14
|
+
# ゲームシステム名の読みがな
|
15
|
+
#
|
16
|
+
# 「ゲームシステム名の読みがなの設定方法」(docs/dicebot_sort_key.md)を参考にして
|
17
|
+
# 設定してください
|
18
|
+
SORT_KEY = 'こんういくたあとらいふ'
|
19
|
+
|
20
|
+
# ダイスボットの使い方
|
21
|
+
HELP_MESSAGE = <<~MESSAGETEXT
|
22
|
+
xCD@z>=y: x個の10面ダイスで目標値y、クリティカルラインzの判定を行う
|
23
|
+
SLT: 技能レベル表を振る
|
24
|
+
DCT: 遅延イベント表を振る
|
25
|
+
MESSAGETEXT
|
26
|
+
|
27
|
+
TABLES = {
|
28
|
+
"SLT" => DiceTable::Table.new(
|
29
|
+
"技能ランク表",
|
30
|
+
"2D10",
|
31
|
+
[
|
32
|
+
"ランク外",
|
33
|
+
"E-",
|
34
|
+
"E",
|
35
|
+
"E+",
|
36
|
+
"D-",
|
37
|
+
"D",
|
38
|
+
"D+",
|
39
|
+
"C-",
|
40
|
+
"C",
|
41
|
+
"C+",
|
42
|
+
"B-",
|
43
|
+
"B",
|
44
|
+
"B+",
|
45
|
+
"A-",
|
46
|
+
"A",
|
47
|
+
"A+",
|
48
|
+
"S-",
|
49
|
+
"S",
|
50
|
+
"S+",
|
51
|
+
]
|
52
|
+
),
|
53
|
+
"DCT" => DiceTable::Table.new(
|
54
|
+
"遅延イベント表",
|
55
|
+
"1D10",
|
56
|
+
[
|
57
|
+
"状況遅延Ⅰ(全員の初期リソースを-1する)",
|
58
|
+
"状況遅延Ⅱ(全員の初期リソースを-1する)",
|
59
|
+
"状況遅延Ⅲ(全員の初期リソースを-2する)",
|
60
|
+
"武装を許すⅠ(ボスの攻撃ダイスを+1dする)",
|
61
|
+
"武装を許すⅡ(脅威度4以下のエネミーの攻撃ダイスを2体まで+1dする)",
|
62
|
+
"武装を許すⅢ(脅威度3以下のエネミーの攻撃ダイスを1体+2dする)",
|
63
|
+
"緊急出撃Ⅰ(ランダムなPCのHPを-1する)",
|
64
|
+
"緊急出撃Ⅱ(ランダムなPCのHPを-1する)",
|
65
|
+
"緊急出撃Ⅲ(ランダムなPC2人のHPを-1する)",
|
66
|
+
"絶望(ダイスを二度振り、二つ適用する)",
|
67
|
+
]
|
68
|
+
),
|
69
|
+
}.freeze
|
70
|
+
|
71
|
+
# ダイスボットで使用するコマンドを配列で列挙する
|
72
|
+
register_prefix("[-+*0-9\(\)]*CD", TABLES.keys)
|
73
|
+
|
74
|
+
def initialize(command)
|
75
|
+
super(command)
|
76
|
+
|
77
|
+
@sides_implicit_d = 10
|
78
|
+
end
|
79
|
+
|
80
|
+
def eval_game_system_specific_command(command)
|
81
|
+
debug("eval_game_system_specific_command Begin")
|
82
|
+
|
83
|
+
return roll_command(command) || roll_tables(command, TABLES)
|
84
|
+
end
|
85
|
+
|
86
|
+
def roll_command(command)
|
87
|
+
parser = Command::Parser.new('CD', round_type: round_type)
|
88
|
+
.has_prefix_number
|
89
|
+
.enable_critical
|
90
|
+
.restrict_cmp_op_to(:>=)
|
91
|
+
cmd = parser.parse(command)
|
92
|
+
|
93
|
+
unless cmd
|
94
|
+
return nil
|
95
|
+
end
|
96
|
+
|
97
|
+
dice_list = @randomizer.roll_barabara(cmd.prefix_number, 10)
|
98
|
+
critical = cmd.critical&.clamp(cmd.target_number, 10) || 10
|
99
|
+
succeed_num = dice_list.count { |x| x >= cmd.target_number }
|
100
|
+
critical_num = dice_list.count { |x| x >= critical }
|
101
|
+
|
102
|
+
text = [
|
103
|
+
cmd.to_s,
|
104
|
+
dice_list.join(','),
|
105
|
+
critical_num > 0 ? "クリティカル数#{critical_num}" : nil,
|
106
|
+
"成功数#{succeed_num + critical_num}",
|
107
|
+
].compact.join(" > ")
|
108
|
+
|
109
|
+
return Result.new.tap do |r|
|
110
|
+
r.success = succeed_num > 0
|
111
|
+
r.critical = critical_num > 0
|
112
|
+
r.text = text
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|