bcdice 3.1.0 → 3.3.0

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.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +78 -1
  3. data/README.md +1 -1
  4. data/i18n/MagicaLogia/zh_hans.yml +564 -0
  5. data/i18n/StellarKnights/ja_jp.yml +498 -0
  6. data/i18n/StellarKnights/ko_kr.yml +498 -0
  7. data/i18n/zh_hans.yml +7 -0
  8. data/lib/bcdice/command/parsed.rb +11 -3
  9. data/lib/bcdice/command/parser.rb +179 -100
  10. data/lib/bcdice/common_command/add_dice.rb +1 -1
  11. data/lib/bcdice/common_command/barabara_dice/node.rb +2 -2
  12. data/lib/bcdice/common_command/barabara_dice/result.rb +6 -0
  13. data/lib/bcdice/common_command/calc.rb +1 -1
  14. data/lib/bcdice/dice_table.rb +2 -0
  15. data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
  16. data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
  17. data/lib/bcdice/dice_table/sai_fic_skill_table.rb +1 -1
  18. data/lib/bcdice/game_system.rb +6 -0
  19. data/lib/bcdice/game_system/AceKillerGene.rb +1 -1
  20. data/lib/bcdice/game_system/Ainecadette.rb +68 -0
  21. data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
  22. data/lib/bcdice/game_system/Alsetto.rb +1 -1
  23. data/lib/bcdice/game_system/AlterRaise.rb +2 -2
  24. data/lib/bcdice/game_system/Amadeus.rb +110 -93
  25. data/lib/bcdice/game_system/AngelGear.rb +2 -2
  26. data/lib/bcdice/game_system/AnimaAnimus.rb +16 -9
  27. data/lib/bcdice/game_system/Arianrhod.rb +6 -8
  28. data/lib/bcdice/game_system/Avandner.rb +1 -1
  29. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  30. data/lib/bcdice/game_system/BattleTech.rb +109 -28
  31. data/lib/bcdice/game_system/BeastBindTrinity.rb +28 -12
  32. data/lib/bcdice/game_system/BeginningIdol.rb +5 -5
  33. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +5 -5
  34. data/lib/bcdice/game_system/BladeOfArcana.rb +1 -1
  35. data/lib/bcdice/game_system/BlindMythos.rb +39 -38
  36. data/lib/bcdice/game_system/BloodCrusade.rb +6 -7
  37. data/lib/bcdice/game_system/BloodMoon.rb +9 -8
  38. data/lib/bcdice/game_system/CardRanker.rb +8 -7
  39. data/lib/bcdice/game_system/ChaosFlare.rb +21 -15
  40. data/lib/bcdice/game_system/Chill.rb +10 -10
  41. data/lib/bcdice/game_system/Chill3.rb +9 -9
  42. data/lib/bcdice/game_system/CodeLayerd.rb +39 -39
  43. data/lib/bcdice/game_system/ColossalHunter.rb +34 -47
  44. data/lib/bcdice/game_system/CrashWorld.rb +1 -1
  45. data/lib/bcdice/game_system/Cthulhu.rb +1 -1
  46. data/lib/bcdice/game_system/Cthulhu7th.rb +48 -10
  47. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +2 -2
  48. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +2 -2
  49. data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +1 -1
  50. data/lib/bcdice/game_system/Cthulhu_Korean.rb +1 -1
  51. data/lib/bcdice/game_system/DarkBlaze.rb +0 -11
  52. data/lib/bcdice/game_system/DarkDaysDrive.rb +8 -7
  53. data/lib/bcdice/game_system/DeadlineHeroes.rb +11 -10
  54. data/lib/bcdice/game_system/DemonParasite.rb +5 -13
  55. data/lib/bcdice/game_system/DesperateRun.rb +1 -1
  56. data/lib/bcdice/game_system/DoubleCross.rb +3 -1
  57. data/lib/bcdice/game_system/Dracurouge.rb +1 -1
  58. data/lib/bcdice/game_system/EclipsePhase.rb +14 -14
  59. data/lib/bcdice/game_system/Elric.rb +18 -14
  60. data/lib/bcdice/game_system/Elysion.rb +1 -1
  61. data/lib/bcdice/game_system/EmbryoMachine.rb +9 -8
  62. data/lib/bcdice/game_system/Emoklore.rb +25 -20
  63. data/lib/bcdice/game_system/Fiasco.rb +1 -1
  64. data/lib/bcdice/game_system/FilledWith.rb +205 -1272
  65. data/lib/bcdice/game_system/FutariSousa.rb +12 -10
  66. data/lib/bcdice/game_system/GURPS.rb +17 -28
  67. data/lib/bcdice/game_system/Garako.rb +1 -1
  68. data/lib/bcdice/game_system/GardenOrder.rb +12 -7
  69. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
  70. data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
  71. data/lib/bcdice/game_system/Gorilla.rb +2 -8
  72. data/lib/bcdice/game_system/GranCrest.rb +18 -11
  73. data/lib/bcdice/game_system/Gundog.rb +9 -8
  74. data/lib/bcdice/game_system/GundogRevised.rb +10 -9
  75. data/lib/bcdice/game_system/GundogZero.rb +1 -1
  76. data/lib/bcdice/game_system/GurpsFW.rb +16 -16
  77. data/lib/bcdice/game_system/HarnMaster.rb +19 -26
  78. data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
  79. data/lib/bcdice/game_system/Hieizan.rb +12 -21
  80. data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
  81. data/lib/bcdice/game_system/HuntersMoon.rb +5 -10
  82. data/lib/bcdice/game_system/InfiniteFantasia.rb +19 -17
  83. data/lib/bcdice/game_system/Insane.rb +13 -20
  84. data/lib/bcdice/game_system/IthaWenUa.rb +8 -15
  85. data/lib/bcdice/game_system/JamesBond.rb +10 -10
  86. data/lib/bcdice/game_system/JekyllAndHyde.rb +1 -1
  87. data/lib/bcdice/game_system/Kamigakari.rb +1 -1
  88. data/lib/bcdice/game_system/KanColle.rb +4 -9
  89. data/lib/bcdice/game_system/KemonoNoMori.rb +26 -39
  90. data/lib/bcdice/game_system/KillDeathBusiness.rb +7 -15
  91. data/lib/bcdice/game_system/KurayamiCrying.rb +141 -2
  92. data/lib/bcdice/game_system/LiveraDoll.rb +254 -304
  93. data/lib/bcdice/game_system/LogHorizon.rb +13 -10
  94. data/lib/bcdice/game_system/MagicaLogia_SimplifiedChinese.rb +66 -0
  95. data/lib/bcdice/game_system/MeikyuDays.rb +10 -8
  96. data/lib/bcdice/game_system/MeikyuKingdom.rb +26 -26
  97. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +5 -4
  98. data/lib/bcdice/game_system/MetalHead.rb +12 -22
  99. data/lib/bcdice/game_system/MetalHeadExtream.rb +5 -5
  100. data/lib/bcdice/game_system/MonotoneMuseum.rb +8 -6
  101. data/lib/bcdice/game_system/Nechronica.rb +63 -90
  102. data/lib/bcdice/game_system/NinjaSlayer.rb +6 -7
  103. data/lib/bcdice/game_system/NjslyrBattle.rb +8 -11
  104. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
  105. data/lib/bcdice/game_system/Paradiso.rb +3 -3
  106. data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
  107. data/lib/bcdice/game_system/Peekaboo.rb +4 -9
  108. data/lib/bcdice/game_system/Pendragon.rb +7 -7
  109. data/lib/bcdice/game_system/PhantasmAdventure.rb +8 -8
  110. data/lib/bcdice/game_system/Postman.rb +1 -1
  111. data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
  112. data/lib/bcdice/game_system/Raisondetre.rb +2 -2
  113. data/lib/bcdice/game_system/Revulture.rb +123 -0
  114. data/lib/bcdice/game_system/RuneQuest.rb +8 -8
  115. data/lib/bcdice/game_system/Ryutama.rb +1 -1
  116. data/lib/bcdice/game_system/SRS.rb +17 -16
  117. data/lib/bcdice/game_system/SamsaraBallad.rb +38 -11
  118. data/lib/bcdice/game_system/Satasupe.rb +32 -32
  119. data/lib/bcdice/game_system/ScreamHighSchool.rb +5 -5
  120. data/lib/bcdice/game_system/SharedFantasia.rb +19 -23
  121. data/lib/bcdice/game_system/ShinobiGami.rb +14 -6
  122. data/lib/bcdice/game_system/Skynauts.rb +103 -142
  123. data/lib/bcdice/game_system/SkynautsBouken.rb +228 -0
  124. data/lib/bcdice/game_system/StarryDolls.rb +318 -0
  125. data/lib/bcdice/game_system/SteamPunkers.rb +11 -6
  126. data/lib/bcdice/game_system/StellarKnights.rb +85 -706
  127. data/lib/bcdice/game_system/StellarKnights_Korean.rb +79 -0
  128. data/lib/bcdice/game_system/SterileLife.rb +2 -3
  129. data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -1
  130. data/lib/bcdice/game_system/StratoShout.rb +8 -16
  131. data/lib/bcdice/game_system/Strave.rb +1 -1
  132. data/lib/bcdice/game_system/SwordWorld.rb +16 -7
  133. data/lib/bcdice/game_system/SwordWorld2_0.rb +2 -2
  134. data/lib/bcdice/game_system/SwordWorld2_5.rb +2 -2
  135. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  136. data/lib/bcdice/game_system/TokumeiTenkousei.rb +4 -3
  137. data/lib/bcdice/game_system/TokyoGhostResearch.rb +1 -1
  138. data/lib/bcdice/game_system/TrinitySeven.rb +279 -280
  139. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
  140. data/lib/bcdice/game_system/Utakaze.rb +53 -48
  141. data/lib/bcdice/game_system/Villaciel.rb +1 -1
  142. data/lib/bcdice/game_system/WARPS.rb +11 -9
  143. data/lib/bcdice/game_system/WaresBlade.rb +4 -9
  144. data/lib/bcdice/game_system/Warhammer.rb +15 -6
  145. data/lib/bcdice/game_system/Warhammer4.rb +15 -11
  146. data/lib/bcdice/game_system/WitchQuest.rb +1 -1
  147. data/lib/bcdice/game_system/YankeeYogSothoth.rb +4 -9
  148. data/lib/bcdice/game_system/Yggdrasill.rb +1 -1
  149. data/lib/bcdice/game_system/ZettaiReido.rb +20 -25
  150. data/lib/bcdice/game_system/filled_with/enemy_data_tables.rb +322 -0
  151. data/lib/bcdice/game_system/filled_with/event_tables.rb +392 -0
  152. data/lib/bcdice/game_system/filled_with/tresure_tables.rb +179 -0
  153. data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +1 -1
  154. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +4 -4
  155. data/lib/bcdice/game_system/sword_world/rating_parser.rb +1 -1
  156. data/lib/bcdice/game_system/sword_world/transcendent_test.rb +26 -8
  157. data/lib/bcdice/repl.rb +1 -1
  158. data/lib/bcdice/result.rb +26 -0
  159. data/lib/bcdice/version.rb +1 -1
  160. metadata +18 -4
@@ -176,8 +176,7 @@ module BCDice
176
176
  command = bRollCommand(at.num, at.difficulty)
177
177
  roll_result = BCDice::CommonCommand::BarabaraDice.eval(command, self, @randomizer)
178
178
 
179
- values = roll_result.rands.map { |v, _| v }
180
- num_of_max_values = values.count(6)
179
+ num_of_max_values = roll_result.last_dice_list.count(6)
181
180
 
182
181
  parts = [roll_result.text]
183
182
 
@@ -195,7 +194,7 @@ module BCDice
195
194
  command = bRollCommand(el.num, el.difficulty)
196
195
  roll_result = BCDice::CommonCommand::BarabaraDice.eval(command, self, @randomizer)
197
196
 
198
- values = roll_result.rands.map { |v, _| v }
197
+ values = roll_result.last_dice_list
199
198
  num_of_max_values = values.count(6)
200
199
  sum_of_true_values = values.count { |v| v >= el.difficulty }
201
200
 
@@ -253,10 +252,10 @@ module BCDice
253
252
 
254
253
  # ダイスボットで使用するコマンドを配列で列挙する
255
254
  register_prefix(
256
- 'NJ\d+',
257
- 'EV\d+',
258
- 'AT\d+',
259
- 'EL\d+',
255
+ 'NJ',
256
+ 'EV',
257
+ 'AT',
258
+ 'EL',
260
259
  TABLES.keys
261
260
  )
262
261
  end
@@ -21,21 +21,18 @@ module BCDice
21
21
  INFO_MESSAGE_TEXT
22
22
 
23
23
  # ゲーム別成功度判定(2D6)
24
- def check_2D6(total, _dice_total, dice_list, cmp_op, target)
25
- return '' if target == '?'
26
- return '' if cmp_op != :<=
24
+ def result_2d6(total, _dice_total, dice_list, cmp_op, target)
25
+ return Result.nothing if target == "?"
26
+ return nil if cmp_op != :<=
27
27
 
28
- return success_text(total, target) + juuten(dice_list)
29
- end
28
+ result = (total <= target ? Result.success("成功") : Result.failure("失敗"))
29
+ result.text += juuten(dice_list)
30
30
 
31
- def success_text(total, target)
32
- if total <= target
33
- " > 成功"
34
- else
35
- " > 失敗"
36
- end
31
+ return result
37
32
  end
38
33
 
34
+ private
35
+
39
36
  def juuten(dice_list)
40
37
  juuten = dice_list.count(1) + dice_list.count(6)
41
38
 
@@ -127,7 +127,7 @@ module BCDice
127
127
  return "失敗"
128
128
  end
129
129
 
130
- register_prefix('\d*JD', 'RETP?\d+', 'DNGNP?\d+', TABLES.keys)
130
+ register_prefix('\d*JD', 'RETP?', 'DNGNP?', TABLES.keys)
131
131
  end
132
132
  end
133
133
  end
@@ -25,7 +25,7 @@ module BCDice
25
25
   例)DC4:【攻撃力】4でダメージチェック DC5[20]:【攻撃力】5でダメージチェック、うち1つは20mm機銃 DC5[20,30]:【攻撃力】5でダメージチェック、うち1つは20mm機銃、うち1つは30mmガンポッド
26
26
  MESSAGETEXT
27
27
 
28
- register_prefix('(\d+)*D20<=', '(\d+)*CP', 'RMT', 'TOT', 'EXT', 'SUT', 'DC(\d+)')
28
+ register_prefix('\d*D20<=', '\d*CP', 'RMT', 'TOT', 'EXT', 'SUT', 'DC')
29
29
 
30
30
  def eval_game_system_specific_command(command) # ダイスロールコマンド
31
31
  # 通常判定部分をgetJudgeResultコマンドに切り分け
@@ -53,13 +53,13 @@ module BCDice
53
53
  # 通常判定
54
54
  def getJudgeResult(command)
55
55
  case command
56
- when /^(\d+)*D20<=(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
56
+ when /^(\d+)?D20<=(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
57
57
  number = (Regexp.last_match(1) || 1).to_i # ダイス数。省略時は1
58
58
  target = (Regexp.last_match(2) || 14).to_i # 目標値。省略時は14 if 空白 then 14 else 記載の値
59
59
  fumble1 = (Regexp.last_match(4) || 21).to_i # 追加ファンブル値。省略時は21
60
60
  fumble2 = (Regexp.last_match(6) || 21).to_i # 追加ファンブル値。省略時は21
61
61
  critical = (Regexp.last_match(8) || 21).to_i # 追加クリティカル値。省略時は21
62
- when /^(\d+)*CP(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
62
+ when /^(\d+)?CP(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
63
63
  number = (Regexp.last_match(1) || 1).to_i
64
64
  target = (Regexp.last_match(2) || 14).to_i
65
65
  fumble1 = (Regexp.last_match(4) || 21).to_i
@@ -26,7 +26,7 @@ module BCDice
26
26
  ・D66ダイスあり
27
27
  INFO_MESSAGE_TEXT
28
28
 
29
- register_prefix('(N|A|M|U|C|)?URGE\d+')
29
+ register_prefix('[NAMUC]?URGE')
30
30
 
31
31
  def get_urge(string) # パラサイトブラッドの衝動表
32
32
  unless /(\w*)URGE\s*(\d+)/i =~ string
@@ -45,18 +45,13 @@ module BCDice
45
45
  end
46
46
 
47
47
  # ゲーム別成功度判定(2D6)
48
- def check_2D6(total, dice_total, _dice_list, cmp_op, target)
49
- return '' if target == '?'
50
- return '' unless cmp_op == :>=
48
+ def result_2d6(_total, dice_total, _dice_list, cmp_op, _target)
49
+ return nil unless cmp_op == :>=
51
50
 
52
51
  if dice_total <= 2
53
- return "ファンブル(【眠気】が1d6点上昇)"
52
+ Result.fumble("ファンブル(【眠気】が1d6点上昇)")
54
53
  elsif dice_total >= 12
55
- return "スペシャル(【魔力】あるいは【眠気】が1d6点回復)"
56
- elsif total >= target
57
- return " > 成功"
58
- else
59
- return " > 失敗"
54
+ Result.critical("スペシャル(【魔力】あるいは【眠気】が1d6点回復)")
60
55
  end
61
56
  end
62
57
 
@@ -18,20 +18,20 @@ module BCDice
18
18
  INFO_MESSAGE_TEXT
19
19
 
20
20
  # ゲーム別成功度判定(1d20)
21
- def check_1D20(total, _dice_total, cmp_op, target)
22
- return '' if target == '?'
23
- return '' unless cmp_op == :<=
21
+ def result_1d20(total, _dice_total, cmp_op, target)
22
+ return Result.nothing if target == '?'
23
+ return nil unless cmp_op == :<=
24
24
 
25
25
  if total <= target
26
26
  if (total >= (40 - target)) || (total == target)
27
- "クリティカル"
27
+ Result.critical("クリティカル")
28
28
  else
29
- "成功"
29
+ Result.success("成功")
30
30
  end
31
31
  elsif total == 20
32
- "ファンブル"
32
+ Result.fumble("ファンブル")
33
33
  else
34
- "失敗"
34
+ Result.failure("失敗")
35
35
  end
36
36
  end
37
37
  end
@@ -18,9 +18,9 @@ module BCDice
18
18
  INFO_MESSAGE_TEXT
19
19
 
20
20
  # ゲーム別成功度判定(1d20)
21
- def check_1D20(total, _dice_total, cmp_op, diff)
22
- return '' if diff == '?'
23
- return '' unless cmp_op == :<=
21
+ def result_1d20(total, _dice_total, cmp_op, diff)
22
+ return Result.nothing if diff == '?'
23
+ return nil unless cmp_op == :<=
24
24
 
25
25
  # 技能値の修正を計算する
26
26
  skill_mod = 0
@@ -46,7 +46,7 @@ module BCDice
46
46
  else
47
47
  fum_str += "-#{skill_mod}=#{fum_num}"
48
48
  end
49
- return "致命的失敗(#{fum_str})"
49
+ return Result.fumble("致命的失敗(#{fum_str})")
50
50
 
51
51
  elsif (total <= critical) || (total <= 1)
52
52
  crit_num = dice_now + skill_mod
@@ -54,14 +54,14 @@ module BCDice
54
54
  crit_num = 1 if crit_num < 1
55
55
 
56
56
  if skill_mod < 0
57
- return "成功"
57
+ return Result.success("成功")
58
58
  end
59
59
 
60
- return "決定的成功(#{dice_now}+#{skill_mod}=#{crit_num})"
60
+ return Result.critical("決定的成功(#{dice_now}+#{skill_mod}=#{crit_num})")
61
61
  elsif total <= diff
62
- return "成功"
62
+ return Result.success("成功")
63
63
  else
64
- return "失敗"
64
+ return Result.failure("失敗")
65
65
  end
66
66
  end
67
67
  end
@@ -38,7 +38,7 @@ module BCDice
38
38
  MESSAGETEXT
39
39
 
40
40
  register_prefix(
41
- 'WEA\d*',
41
+ 'WEA',
42
42
  '(\d+)?PO',
43
43
  'FRE'
44
44
  )
@@ -47,7 +47,7 @@ module BCDice
47
47
   ・プッシュ時のキャスティング・ロールの失敗(Failed Casting Effects)表 FCE
48
48
  INFO_MESSAGE_TEXT
49
49
 
50
- register_prefix('CC\(\d+\)', 'CC', 'CBR\(\d+,\d+\)', 'FAR', 'BMR', 'BMS', 'FCE', 'PH', 'MA', 'IT')
50
+ register_prefix('CC', 'CBR', 'FAR', 'BMR', 'BMS', 'FCE', 'PH', 'MA', 'IT')
51
51
 
52
52
  def eval_game_system_specific_command(command)
53
53
  case command
@@ -39,8 +39,8 @@ module BCDice
39
39
  end
40
40
 
41
41
  register_prefix(
42
- '(-)?(\d+)?RD(\d+)?(@(\d+))?',
43
- '(-)?(\d+)?DD([1-9])?([\+\-]\d+)?'
42
+ '(-)?(\d+)?RD',
43
+ '(-)?(\d+)?DD'
44
44
  )
45
45
 
46
46
  def eval_game_system_specific_command(command)
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Revulture < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'Revulture'
8
+
9
+ # ゲームシステム名
10
+ NAME = '光砕のリヴァルチャー'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'こうさいのりうあるちやあ'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~HELP
17
+ ■アタック判定( xAT, xATK, xATTACK )
18
+ x: ダイス数(加算 + と除算 / を使用可能)
19
+ 例) 3AT, 4ATK, 5+6ATTACK, 15/2AT
20
+
21
+ □アタック判定 目標値つき( xAT<=y, xATK<=y, xATTACK<=y )
22
+ x: ダイス数(加算 + と除算 / を使用可能)
23
+ y: 目標値( 1 以上 6 以下。加算 + を使用可能)
24
+ 例) 3AT<=4, 3AT<=2+1
25
+
26
+ □アタック判定 目標値&追加ダメージつき( xAT<=y[>=a:+b], xATK<=y[>=a:+b], xATTACK<=y[z] )
27
+ x: ダイス数(加算 + と除算 / を使用可能)
28
+ y: 目標値( 1 以上 6 以下。加算 + を使用可能)
29
+ z: 追加ダメージの規則(詳細は後述)(※複数同時に指定可能)
30
+
31
+ ▽追加ダメージの規則 [a:+b]
32
+ a: ヒット数が a なら
33
+  =a (ヒット数が a に等しい)
34
+  >=a (ヒット数が a 以上)
35
+ b: ダメージを b 点追加
36
+
37
+ 例) 3AT<=4[>=2:+3] #ルールブックp056「グレングラントAR」
38
+ 例) 2AT<=4[=1:+5][>=2:+8] #ルールブックp067「ファーボル・ドラゴンブレス」
39
+ HELP
40
+
41
+ ATTACK_ROLL_REG = %r{^(\d+([+/]\d+)*)?AT(TACK|K)?(<=([1-6](\+\d)*))?((\[>?=\d+:\+\d+\])+)?}i.freeze
42
+ register_prefix('\d+([+\/]\d+)*AT')
43
+
44
+ def eval_game_system_specific_command(command)
45
+ if (m = ATTACK_ROLL_REG.match(command))
46
+ roll_attack(m[1], m[5], m[7])
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def roll_attack(dice_count_expression, border_expression, additional_damage_rules)
53
+ dice_count = Arithmetic.eval(dice_count_expression, round_type: RoundType::FLOOR)
54
+ border = Arithmetic.eval(border_expression, round_type: RoundType::FLOOR).clamp(1, 6) if border_expression
55
+
56
+ command = make_command_text(dice_count, border, additional_damage_rules)
57
+
58
+ if dice_count <= 0
59
+ return "#{command} > ダイス数が 0 です"
60
+ elsif border.nil? && additional_damage_rules
61
+ return "#{command} > 目標値が指定されていないため、追加ダメージを算出できません"
62
+ end
63
+
64
+ dices = @randomizer.roll_barabara(dice_count, 6).sort
65
+
66
+ critical_hit_count = dices.count(1)
67
+ hit_count = dices.count { |dice| dice <= border } + critical_hit_count if border
68
+ damage = calc_damage(hit_count, additional_damage_rules)
69
+
70
+ message_elements = []
71
+ message_elements << command
72
+ message_elements << dices.join(',')
73
+ message_elements << "クリティカル #{critical_hit_count}" if critical_hit_count > 0
74
+ message_elements << "ヒット数 #{hit_count}" if hit_count
75
+ message_elements << "ダメージ #{damage}" if damage
76
+
77
+ Result.new(message_elements.join(' > ')).tap do |r|
78
+ r.condition = hit_count > 0 if hit_count
79
+ r.critical = critical_hit_count > 0
80
+ end
81
+ end
82
+
83
+ def make_command_text(dice_count, border, additional_damage_rules)
84
+ command = "#{dice_count}attack"
85
+ command += "<=#{border}" if border
86
+ command += additional_damage_rules if additional_damage_rules
87
+
88
+ "(#{command})"
89
+ end
90
+
91
+ def calc_damage(hit_count, additional_damage_rules)
92
+ return nil unless additional_damage_rules
93
+
94
+ damage = hit_count
95
+ parse_additional_damage_rules(additional_damage_rules).each do |rule|
96
+ if rule[:condition].call(hit_count)
97
+ damage += rule[:additinal_damage]
98
+ end
99
+ end
100
+
101
+ damage
102
+ end
103
+
104
+ def parse_additional_damage_rules(source)
105
+ source.scan(/\[(>?=)(\d+):\+(\d+)\]/).map do |matched|
106
+ {
107
+ condition: make_additional_damage_condition(matched[0], matched[1].to_i),
108
+ additinal_damage: matched[2].to_i,
109
+ }
110
+ end
111
+ end
112
+
113
+ def make_additional_damage_condition(comparer, comparing_target)
114
+ case comparer
115
+ when '='
116
+ lambda { |hit_count| hit_count == comparing_target }
117
+ when '>='
118
+ lambda { |hit_count| hit_count >= comparing_target }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -18,8 +18,8 @@ module BCDice
18
18
  INFO_MESSAGE_TEXT
19
19
 
20
20
  # ゲーム別成功度判定(1d100)
21
- def check_1D100(total, _dice_total, cmp_op, target)
22
- return '' if target == '?'
21
+ def result_1d100(total, _dice_total, cmp_op, target)
22
+ return Result.nothing if target == '?'
23
23
  return nil unless cmp_op == :<=
24
24
 
25
25
  # RuneQuest QUICK-START RULESを元に修正
@@ -28,18 +28,18 @@ module BCDice
28
28
 
29
29
  if (total <= 1) || (total <= critical_value)
30
30
  # 1は常に決定的成功
31
- "決定的成功"
31
+ Result.critical("決定的成功")
32
32
  elsif total >= 100
33
33
  # 100は常に致命的失敗
34
- "致命的失敗"
34
+ Result.fumble("致命的失敗")
35
35
  elsif total <= (target.to_f / 5).round
36
- "効果的成功"
36
+ Result.success("効果的成功")
37
37
  elsif total <= target
38
- "成功"
38
+ Result.success("成功")
39
39
  elsif total >= 95 + critical_value
40
- "致命的失敗"
40
+ Result.fumble("致命的失敗")
41
41
  else
42
- "失敗"
42
+ Result.failure("失敗")
43
43
  end
44
44
  end
45
45
  end
@@ -21,7 +21,7 @@ module BCDice
21
21
  例)R8,6>=13
22
22
  INFO_MESSAGE_TEXT
23
23
 
24
- register_prefix('R\d+')
24
+ register_prefix('R')
25
25
 
26
26
  def initialize(command)
27
27
  super(command)
@@ -219,7 +219,7 @@ module BCDice
219
219
 
220
220
  # 固有のダイスロールコマンドを実行する
221
221
  # @param [String] command 入力されたコマンド
222
- # @return [String, nil] ダイスロールコマンドの実行結果
222
+ # @return [Result, nil] ダイスロールコマンドの実行結果
223
223
  def eval_game_system_specific_command(command)
224
224
  alias_replaced_with_2d6 = replace_alias_for_srs_roll_with_2d6(command)
225
225
 
@@ -297,7 +297,7 @@ module BCDice
297
297
 
298
298
  # 成功判定を実行する
299
299
  # @param [SRSRollNode] srs_roll 成功判定ノード
300
- # @return [String] 成功判定結果
300
+ # @return [Result] 成功判定結果
301
301
  def execute_srs_roll(srs_roll)
302
302
  dice_list = @randomizer.roll_barabara(2, 6)
303
303
  dice_list.sort! if @sort_add_dice
@@ -307,35 +307,36 @@ module BCDice
307
307
 
308
308
  modified_sum = sum + srs_roll.modifier
309
309
 
310
+ result = compare_result(srs_roll, sum, modified_sum)
311
+
310
312
  parts = [
311
313
  "(#{srs_roll})",
312
314
  "#{sum}[#{dice_str}]#{Format.modifier(srs_roll.modifier)}",
313
315
  modified_sum,
314
- compare_result(srs_roll, sum, modified_sum)
316
+ result.text
315
317
  ]
316
318
 
317
- return parts.compact.join(' > ')
319
+ result.text = parts.compact.join(' > ')
320
+ result
318
321
  end
319
322
 
320
323
  # ダイスロール結果を目標値、クリティカル値、ファンブル値と比較する
321
324
  # @param [SRSRollNode] srs_roll 成功判定ノード
322
325
  # @param [Integer] sum 出目の合計
323
326
  # @param [Integer] modified_sum 修正後の値
324
- # @return [String, nil] 比較結果
327
+ # @return [Result] 比較結果
325
328
  def compare_result(srs_roll, sum, modified_sum)
326
329
  if sum >= srs_roll.critical_value
327
- return '自動成功'
328
- end
329
-
330
- if sum <= srs_roll.fumble_value
331
- return '自動失敗'
332
- end
333
-
334
- if srs_roll.target_value
335
- return modified_sum >= srs_roll.target_value ? '成功' : '失敗'
330
+ Result.critical("自動成功")
331
+ elsif sum <= srs_roll.fumble_value
332
+ Result.fumble("自動失敗")
333
+ elsif srs_roll.target_value.nil?
334
+ Result.new
335
+ elsif modified_sum >= srs_roll.target_value
336
+ Result.success("成功")
337
+ else
338
+ Result.failure("失敗")
336
339
  end
337
-
338
- return nil
339
340
  end
340
341
  end
341
342
  end