bcdice 3.6.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -0
  3. data/i18n/Arianrhod/ja_jp.yml +3 -0
  4. data/i18n/Emoklore/ja_jp.yml +7 -0
  5. data/i18n/FutariSousa/ja_jp.yml +431 -0
  6. data/i18n/LogHorizon/ja_jp.yml +1 -1
  7. data/i18n/SwordWorld/ja_jp.yml +1 -0
  8. data/i18n/SwordWorld/zh_hans.yml +7 -0
  9. data/i18n/SwordWorld2_0/zh_hans.yml +37 -0
  10. data/i18n/SwordWorld2_5/ja_jp.yml +1 -1
  11. data/i18n/SwordWorld2_5/zh_hans.yml +57 -0
  12. data/lib/bcdice/arithmetic/parser.rb +1 -1
  13. data/lib/bcdice/command/parser.rb +1 -1
  14. data/lib/bcdice/common_command/add_dice/parser.rb +106 -74
  15. data/lib/bcdice/common_command/add_dice.rb +1 -1
  16. data/lib/bcdice/common_command/barabara_dice/parser.rb +1 -1
  17. data/lib/bcdice/common_command/calc/parser.rb +1 -1
  18. data/lib/bcdice/common_command/d66_dice.rb +1 -1
  19. data/lib/bcdice/common_command/reroll_dice/parser.rb +1 -1
  20. data/lib/bcdice/common_command/tally_dice/parser.rb +1 -1
  21. data/lib/bcdice/common_command/upper_dice/parser.rb +1 -1
  22. data/lib/bcdice/game_system/AngelGear.rb +1 -1
  23. data/lib/bcdice/game_system/AnimaAnimus.rb +1 -1
  24. data/lib/bcdice/game_system/Arianrhod.rb +4 -4
  25. data/lib/bcdice/game_system/AssaultEngine.rb +3 -3
  26. data/lib/bcdice/game_system/Ayabito.rb +170 -4
  27. data/lib/bcdice/game_system/BeastBindTrinity.rb +1 -1
  28. data/lib/bcdice/game_system/BeginningIdol.rb +4 -2
  29. data/lib/bcdice/game_system/BeginningIdol2022.rb +184 -0
  30. data/lib/bcdice/game_system/BladeOfArcana.rb +3 -3
  31. data/lib/bcdice/game_system/Bloodorium.rb +68 -0
  32. data/lib/bcdice/game_system/ConvictorDrive.rb +117 -0
  33. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
  34. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
  35. data/lib/bcdice/game_system/CyberpunkRed.rb +2 -6
  36. data/lib/bcdice/game_system/DeadlineHeroes.rb +1 -1
  37. data/lib/bcdice/game_system/DungeonsAndDragons5.rb +196 -0
  38. data/lib/bcdice/game_system/EmbryoMachine.rb +4 -4
  39. data/lib/bcdice/game_system/Emoklore.rb +8 -8
  40. data/lib/bcdice/game_system/FutariSousa.rb +31 -5
  41. data/lib/bcdice/game_system/GURPS.rb +1 -1
  42. data/lib/bcdice/game_system/GehennaAn.rb +2 -2
  43. data/lib/bcdice/game_system/GhostLive.rb +144 -0
  44. data/lib/bcdice/game_system/GoblinSlayer.rb +30 -8
  45. data/lib/bcdice/game_system/HunterTheReckoning5th.rb +152 -0
  46. data/lib/bcdice/game_system/IfIfIf.rb +648 -0
  47. data/lib/bcdice/game_system/Kutulu.rb +95 -0
  48. data/lib/bcdice/game_system/LostRoyal.rb +1 -1
  49. data/lib/bcdice/game_system/NobunagasBlackCastle.rb +237 -0
  50. data/lib/bcdice/game_system/OracleEngine.rb +1 -1
  51. data/lib/bcdice/game_system/Raisondetre.rb +1 -1
  52. data/lib/bcdice/game_system/RokumonSekai2.rb +1 -1
  53. data/lib/bcdice/game_system/SajinsenkiAGuS.rb +154 -0
  54. data/lib/bcdice/game_system/Sengensyou.rb +59 -0
  55. data/lib/bcdice/game_system/ShinkuuGakuen.rb +1 -1
  56. data/lib/bcdice/game_system/ShinobiGami.rb +14 -1
  57. data/lib/bcdice/game_system/SkynautsBouken.rb +93 -2
  58. data/lib/bcdice/game_system/StellarLife.rb +1 -1
  59. data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -1
  60. data/lib/bcdice/game_system/SwordWorld.rb +2 -2
  61. data/lib/bcdice/game_system/SwordWorld2_0_SimplifiedChinese.rb +84 -0
  62. data/lib/bcdice/game_system/SwordWorld2_5_SimplifiedChinese.rb +95 -0
  63. data/lib/bcdice/game_system/SwordWorld_SimplifiedChinese.rb +29 -0
  64. data/lib/bcdice/game_system/TherapieSein.rb +2 -2
  65. data/lib/bcdice/game_system/Torg.rb +1 -1
  66. data/lib/bcdice/game_system/TorgEternity.rb +54 -18
  67. data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +26 -12
  68. data/lib/bcdice/game_system/VisionConnect.rb +135 -0
  69. data/lib/bcdice/game_system/Warhammer4.rb +4 -0
  70. data/lib/bcdice/game_system/WorldOfDarkness.rb +54 -50
  71. data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +1 -1
  72. data/lib/bcdice/game_system/filled_with/tresure_tables.rb +1 -1
  73. data/lib/bcdice/game_system/satasupe/tables.rb +1 -1
  74. data/lib/bcdice/game_system/sword_world/rating_parser.rb +1 -1
  75. data/lib/bcdice/game_system.rb +15 -0
  76. data/lib/bcdice/version.rb +1 -1
  77. 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(6) + over_modify * 2
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 > target
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?)((?:[+\-]\d+)+)?(?:%(-?\d+))?(?:@([+\-\d]+))?(?:#(A)?([+\-\d]+))?(?:\$([1-6]+))?(?:&([1-6]))?(?:([>=]+)(\d+))?$/.match(@command)
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]*)([+\-]\d+)?$/.match(command)
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+)([+\-]\d+)?$/.match(command)
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
@@ -210,7 +210,7 @@ module BCDice
210
210
  }
211
211
 
212
212
  # 難度變更用Loop
213
- (0..3).each do |more_difficlty|
213
+ 4.times do |more_difficlty|
214
214
  output += getNextDifficltyMessage(more_difficlty)
215
215
 
216
216
  # ペナルティダイスを減らしながらロール用ループ削減獎勵骰時角色用Loop