bcdice 3.0.0.pre.alpha.1 → 3.0.0.pre.alpha.2

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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/.rubocop.yml +12 -0
  4. data/.rubocop_todo.yml +1 -0
  5. data/CHANGELOG.md +34 -0
  6. data/Gemfile +6 -3
  7. data/Rakefile +52 -18
  8. data/bcdice.gemspec +2 -0
  9. data/i18n/Amadeus/ja_jp.yml +386 -0
  10. data/i18n/Amadeus/ko_kr.yml +148 -0
  11. data/i18n/Cthulhu/ja_jp.yml +11 -0
  12. data/i18n/Cthulhu/ko_kr.yml +11 -0
  13. data/i18n/Cthulhu/zh_hant.yml +11 -0
  14. data/i18n/DetatokoSaga/ja_jp.yml +74 -0
  15. data/i18n/DetatokoSaga/ko_kr.yml +74 -0
  16. data/i18n/DoubleCross/ja_jp.yml +53 -0
  17. data/i18n/DoubleCross/ko_kr.yml +53 -0
  18. data/i18n/Dracurouge/ja_jp.yml +1374 -0
  19. data/i18n/Dracurouge/ko_kr.yml +295 -0
  20. data/i18n/Fiasco/ja_jp.yml +10 -0
  21. data/i18n/Fiasco/ko_kr.yml +10 -0
  22. data/i18n/FutariSousa/ja_jp.yml +720 -0
  23. data/i18n/FutariSousa/ko_kr.yml +746 -0
  24. data/i18n/Insane/ja_jp.yml +454 -0
  25. data/i18n/Insane/ko_kr.yml +502 -0
  26. data/i18n/Kamigakari/ja_jp.yml +276 -0
  27. data/i18n/Kamigakari/ko_kr.yml +204 -0
  28. data/i18n/KillDeathBusiness/ja_jp.yml +1092 -0
  29. data/i18n/KillDeathBusiness/ko_kr.yml +1062 -0
  30. data/i18n/LogHorizon/ja_jp.yml +3082 -0
  31. data/i18n/LogHorizon/ko_kr.yml +923 -0
  32. data/i18n/MagicaLogia/ja_jp.yml +564 -0
  33. data/i18n/MonotoneMuseum/ja_jp.yml +525 -0
  34. data/i18n/MonotoneMuseum/ko_kr.yml +89 -0
  35. data/i18n/Nechronica/ja_jp.yml +57 -0
  36. data/i18n/Nechronica/ko_kr.yml +14 -0
  37. data/i18n/StratoShout/ja_jp.yml +160 -0
  38. data/i18n/StratoShout/ko_kr.yml +160 -0
  39. data/i18n/ja_jp.yml +5 -0
  40. data/i18n/ko_kr.yml +7 -0
  41. data/i18n/zh_hant.yml +3 -0
  42. data/lib/bcdice/arithmetic/node.rb +154 -0
  43. data/lib/bcdice/base.rb +87 -101
  44. data/lib/bcdice/common_command.rb +2 -0
  45. data/lib/bcdice/common_command/add_dice.rb +5 -41
  46. data/lib/bcdice/common_command/add_dice/node.rb +92 -16
  47. data/lib/bcdice/common_command/add_dice/parser.rb +374 -274
  48. data/lib/bcdice/common_command/add_dice/parser.y +153 -0
  49. data/lib/bcdice/common_command/add_dice/randomizer.rb +25 -33
  50. data/lib/bcdice/common_command/barabara_dice.rb +6 -47
  51. data/lib/bcdice/common_command/barabara_dice/node.rb +84 -0
  52. data/lib/bcdice/common_command/barabara_dice/parser.rb +336 -0
  53. data/lib/bcdice/common_command/barabara_dice/parser.y +107 -0
  54. data/lib/bcdice/common_command/calc.rb +7 -30
  55. data/lib/bcdice/common_command/calc/node.rb +30 -0
  56. data/lib/bcdice/common_command/calc/parser.rb +271 -0
  57. data/lib/bcdice/common_command/calc/parser.y +79 -0
  58. data/lib/bcdice/common_command/choice.rb +137 -19
  59. data/lib/bcdice/common_command/d66_dice.rb +48 -34
  60. data/lib/bcdice/common_command/lexer.rb +46 -0
  61. data/lib/bcdice/common_command/repeat.rb +102 -0
  62. data/lib/bcdice/common_command/reroll_dice.rb +8 -158
  63. data/lib/bcdice/common_command/reroll_dice/node.rb +198 -0
  64. data/lib/bcdice/common_command/reroll_dice/parser.rb +421 -0
  65. data/lib/bcdice/common_command/reroll_dice/parser.y +158 -0
  66. data/lib/bcdice/common_command/upper_dice.rb +10 -129
  67. data/lib/bcdice/common_command/upper_dice/node.rb +181 -0
  68. data/lib/bcdice/common_command/upper_dice/parser.rb +412 -0
  69. data/lib/bcdice/common_command/upper_dice/parser.y +143 -0
  70. data/lib/bcdice/common_command/version.rb +9 -17
  71. data/lib/bcdice/deprecated/checker.rb +78 -0
  72. data/lib/bcdice/dice_table/d66_grid_table.rb +8 -0
  73. data/lib/bcdice/dice_table/d66_table.rb +10 -0
  74. data/lib/bcdice/dice_table/sai_fic_skill_table.rb +75 -17
  75. data/lib/bcdice/dice_table/sai_fic_skill_table/category.rb +25 -0
  76. data/lib/bcdice/dice_table/sai_fic_skill_table/skill.rb +23 -0
  77. data/lib/bcdice/dice_table/table.rb +8 -0
  78. data/lib/bcdice/game_system.rb +7 -1
  79. data/lib/bcdice/game_system/AFF2e.rb +1 -1
  80. data/lib/bcdice/game_system/AceKillerGene.rb +2 -2
  81. data/lib/bcdice/game_system/Airgetlamh.rb +3 -3
  82. data/lib/bcdice/game_system/Alsetto.rb +1 -1
  83. data/lib/bcdice/game_system/Alshard.rb +1 -1
  84. data/lib/bcdice/game_system/AlterRaise.rb +2 -2
  85. data/lib/bcdice/game_system/Amadeus.rb +46 -507
  86. data/lib/bcdice/game_system/Amadeus_Korean.rb +12 -456
  87. data/lib/bcdice/game_system/AnimaAnimus.rb +1 -1
  88. data/lib/bcdice/game_system/Arianrhod.rb +0 -1
  89. data/lib/bcdice/game_system/ArsMagica.rb +1 -1
  90. data/lib/bcdice/game_system/Avandner.rb +1 -1
  91. data/lib/bcdice/game_system/BBN.rb +1 -1
  92. data/lib/bcdice/game_system/BadLife.rb +1 -1
  93. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  94. data/lib/bcdice/game_system/BeastBindTrinity.rb +1 -2
  95. data/lib/bcdice/game_system/BeginningIdol.rb +2 -3
  96. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +2 -3
  97. data/lib/bcdice/game_system/BladeOfArcana.rb +2 -2
  98. data/lib/bcdice/game_system/BlindMythos.rb +1 -1
  99. data/lib/bcdice/game_system/BloodCrusade.rb +0 -1
  100. data/lib/bcdice/game_system/BloodMoon.rb +0 -1
  101. data/lib/bcdice/game_system/CardRanker.rb +1 -2
  102. data/lib/bcdice/game_system/ChaosFlare.rb +1 -1
  103. data/lib/bcdice/game_system/Chill.rb +1 -1
  104. data/lib/bcdice/game_system/CodeLayerd.rb +1 -1
  105. data/lib/bcdice/game_system/ColossalHunter.rb +1 -2
  106. data/lib/bcdice/game_system/Comes.rb +50 -0
  107. data/lib/bcdice/game_system/CrashWorld.rb +1 -1
  108. data/lib/bcdice/game_system/Cthulhu.rb +94 -97
  109. data/lib/bcdice/game_system/Cthulhu7th.rb +108 -67
  110. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
  111. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
  112. data/lib/bcdice/game_system/CthulhuTech.rb +8 -14
  113. data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +7 -190
  114. data/lib/bcdice/game_system/Cthulhu_Korean.rb +5 -186
  115. data/lib/bcdice/game_system/DarkBlaze.rb +9 -5
  116. data/lib/bcdice/game_system/DarkDaysDrive.rb +17 -15
  117. data/lib/bcdice/game_system/DarkSouls.rb +1 -1
  118. data/lib/bcdice/game_system/DeadlineHeroes.rb +2 -2
  119. data/lib/bcdice/game_system/DemonParasite.rb +1 -2
  120. data/lib/bcdice/game_system/DetatokoSaga.rb +48 -149
  121. data/lib/bcdice/game_system/DetatokoSaga_Korean.rb +6 -274
  122. data/lib/bcdice/game_system/DiceOfTheDead.rb +9 -6
  123. data/lib/bcdice/game_system/DoubleCross.rb +102 -81
  124. data/lib/bcdice/game_system/DoubleCross_Korean.rb +13 -330
  125. data/lib/bcdice/game_system/Dracurouge.rb +376 -1678
  126. data/lib/bcdice/game_system/Dracurouge_Korean.rb +16 -271
  127. data/lib/bcdice/game_system/EarthDawn.rb +1 -1
  128. data/lib/bcdice/game_system/EarthDawn3.rb +1 -1
  129. data/lib/bcdice/game_system/EarthDawn4.rb +1 -1
  130. data/lib/bcdice/game_system/Elysion.rb +3 -4
  131. data/lib/bcdice/game_system/EmbryoMachine.rb +1 -1
  132. data/lib/bcdice/game_system/Emoklore.rb +131 -0
  133. data/lib/bcdice/game_system/EndBreaker.rb +1 -2
  134. data/lib/bcdice/game_system/EtrianOdysseySRS.rb +1 -1
  135. data/lib/bcdice/game_system/Fiasco.rb +87 -70
  136. data/lib/bcdice/game_system/Fiasco_Korean.rb +7 -95
  137. data/lib/bcdice/game_system/FilledWith.rb +462 -566
  138. data/lib/bcdice/game_system/FullMetalPanic.rb +1 -1
  139. data/lib/bcdice/game_system/FutariSousa.rb +103 -938
  140. data/lib/bcdice/game_system/FutariSousa_Korean.rb +7 -948
  141. data/lib/bcdice/game_system/{Gurps.rb → GURPS.rb} +184 -217
  142. data/lib/bcdice/game_system/Garako.rb +131 -39
  143. data/lib/bcdice/game_system/GardenOrder.rb +2 -2
  144. data/lib/bcdice/game_system/GehennaAn.rb +1 -1
  145. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
  146. data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
  147. data/lib/bcdice/game_system/GoldenSkyStories.rb +1 -1
  148. data/lib/bcdice/game_system/Gorilla.rb +1 -1
  149. data/lib/bcdice/game_system/GranCrest.rb +2 -3
  150. data/lib/bcdice/game_system/GundogRevised.rb +1 -1
  151. data/lib/bcdice/game_system/GundogZero.rb +1 -1
  152. data/lib/bcdice/game_system/GurpsFW.rb +2 -3
  153. data/lib/bcdice/game_system/HarnMaster.rb +2 -2
  154. data/lib/bcdice/game_system/HatsuneMiku.rb +1 -2
  155. data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
  156. data/lib/bcdice/game_system/HuntersMoon.rb +1 -2
  157. data/lib/bcdice/game_system/Illusio.rb +2 -2
  158. data/lib/bcdice/game_system/Insane.rb +90 -717
  159. data/lib/bcdice/game_system/Insane_Korean.rb +7 -719
  160. data/lib/bcdice/game_system/Kamigakari.rb +47 -242
  161. data/lib/bcdice/game_system/Kamigakari_Korean.rb +6 -394
  162. data/lib/bcdice/game_system/KanColle.rb +3 -3
  163. data/lib/bcdice/game_system/KemonoNoMori.rb +1 -1
  164. data/lib/bcdice/game_system/KillDeathBusiness.rb +162 -1144
  165. data/lib/bcdice/game_system/KillDeathBusiness_Korean.rb +6 -1459
  166. data/lib/bcdice/game_system/KurayamiCrying.rb +1 -1
  167. data/lib/bcdice/game_system/LiveraDoll.rb +2 -2
  168. data/lib/bcdice/game_system/LogHorizon.rb +350 -3379
  169. data/lib/bcdice/game_system/LogHorizon_Korean.rb +55 -1357
  170. data/lib/bcdice/game_system/LostRecord.rb +0 -1
  171. data/lib/bcdice/game_system/LostRoyal.rb +1 -2
  172. data/lib/bcdice/game_system/MagicaLogia.rb +158 -1044
  173. data/lib/bcdice/game_system/MeikyuDays.rb +1 -2
  174. data/lib/bcdice/game_system/MeikyuKingdom.rb +4 -4
  175. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +4 -5
  176. data/lib/bcdice/game_system/MetalHead.rb +1 -1
  177. data/lib/bcdice/game_system/MetalHeadExtream.rb +2 -2
  178. data/lib/bcdice/game_system/MetallicGuardian.rb +1 -1
  179. data/lib/bcdice/game_system/MonotoneMuseum.rb +38 -239
  180. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +10 -270
  181. data/lib/bcdice/game_system/NSSQ.rb +159 -0
  182. data/lib/bcdice/game_system/Nechronica.rb +34 -73
  183. data/lib/bcdice/game_system/Nechronica_Korean.rb +11 -128
  184. data/lib/bcdice/game_system/NeverCloud.rb +1 -1
  185. data/lib/bcdice/game_system/NightWizard.rb +1 -1
  186. data/lib/bcdice/game_system/NightWizard3rd.rb +1 -1
  187. data/lib/bcdice/game_system/NinjaSlayer.rb +12 -11
  188. data/lib/bcdice/game_system/NjslyrBattle.rb +1 -1
  189. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -2
  190. data/lib/bcdice/game_system/OracleEngine.rb +1 -1
  191. data/lib/bcdice/game_system/OrgaRain.rb +2 -2
  192. data/lib/bcdice/game_system/Paradiso.rb +1 -1
  193. data/lib/bcdice/game_system/Paranoia.rb +1 -1
  194. data/lib/bcdice/game_system/ParanoiaRebooted.rb +1 -1
  195. data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
  196. data/lib/bcdice/game_system/Peekaboo.rb +22 -122
  197. data/lib/bcdice/game_system/Postman.rb +2 -2
  198. data/lib/bcdice/game_system/PulpCthulhu.rb +3 -3
  199. data/lib/bcdice/game_system/Raisondetre.rb +2 -2
  200. data/lib/bcdice/game_system/RecordOfLodossWar.rb +1 -1
  201. data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
  202. data/lib/bcdice/game_system/RokumonSekai2.rb +1 -1
  203. data/lib/bcdice/game_system/RuinBreakers.rb +296 -0
  204. data/lib/bcdice/game_system/Ryutama.rb +1 -1
  205. data/lib/bcdice/game_system/SRS.rb +1 -2
  206. data/lib/bcdice/game_system/SamsaraBallad.rb +1 -1
  207. data/lib/bcdice/game_system/Satasupe.rb +1 -2
  208. data/lib/bcdice/game_system/ScreamHighSchool.rb +2 -2
  209. data/lib/bcdice/game_system/SevenFortressMobius.rb +1 -1
  210. data/lib/bcdice/game_system/ShadowRun5.rb +2 -2
  211. data/lib/bcdice/game_system/SharedFantasia.rb +1 -1
  212. data/lib/bcdice/game_system/ShinMegamiTenseiKakuseihen.rb +1 -1
  213. data/lib/bcdice/game_system/ShinkuuGakuen.rb +2 -2
  214. data/lib/bcdice/game_system/ShinobiGami.rb +1 -2
  215. data/lib/bcdice/game_system/ShoujoTenrankai.rb +2 -2
  216. data/lib/bcdice/game_system/Skynauts.rb +1 -1
  217. data/lib/bcdice/game_system/SteamPunkers.rb +1 -1
  218. data/lib/bcdice/game_system/StellarKnights.rb +1 -2
  219. data/lib/bcdice/game_system/SterileLife.rb +1 -1
  220. data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -2
  221. data/lib/bcdice/game_system/StratoShout.rb +44 -247
  222. data/lib/bcdice/game_system/StratoShout_Korean.rb +6 -282
  223. data/lib/bcdice/game_system/Strave.rb +2 -2
  224. data/lib/bcdice/game_system/SwordWorld.rb +8 -9
  225. data/lib/bcdice/game_system/SwordWorld2_0.rb +2 -3
  226. data/lib/bcdice/game_system/SwordWorld2_5.rb +2 -3
  227. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  228. data/lib/bcdice/game_system/TokumeiTenkousei.rb +1 -1
  229. data/lib/bcdice/game_system/TokyoGhostResearch.rb +2 -2
  230. data/lib/bcdice/game_system/Torg.rb +2 -2
  231. data/lib/bcdice/game_system/Torg1_5.rb +1 -1
  232. data/lib/bcdice/game_system/TorgEternity.rb +1 -1
  233. data/lib/bcdice/game_system/TrinitySeven.rb +1 -1
  234. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
  235. data/lib/bcdice/game_system/TwilightGunsmoke.rb +1 -2
  236. data/lib/bcdice/game_system/UnsungDuet.rb +139 -0
  237. data/lib/bcdice/game_system/Utakaze.rb +1 -1
  238. data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +1 -1
  239. data/lib/bcdice/game_system/Villaciel.rb +1 -2
  240. data/lib/bcdice/game_system/Warhammer.rb +1 -1
  241. data/lib/bcdice/game_system/Warhammer4.rb +329 -0
  242. data/lib/bcdice/game_system/WitchQuest.rb +1 -1
  243. data/lib/bcdice/game_system/WorldOfDarkness.rb +1 -1
  244. data/lib/bcdice/game_system/YankeeYogSothoth.rb +15 -15
  245. data/lib/bcdice/game_system/YearZeroEngine.rb +1 -1
  246. data/lib/bcdice/game_system/ZettaiReido.rb +1 -1
  247. data/lib/bcdice/game_system/filled_with/cook_tables.rb +119 -0
  248. data/lib/bcdice/game_system/filled_with/lot_tables.rb +155 -0
  249. data/lib/bcdice/loader.rb +6 -8
  250. data/lib/bcdice/preprocessor.rb +15 -40
  251. data/lib/bcdice/repl.rb +1 -1
  252. data/lib/bcdice/result.rb +83 -0
  253. data/lib/bcdice/translate.rb +11 -0
  254. data/lib/bcdice/version.rb +1 -1
  255. metadata +80 -4
@@ -32,10 +32,10 @@ module BCDice
32
32
  ※アイデンティティ表はエラッタ適用済です。
33
33
  MESSAGETEXT
34
34
 
35
- register_prefix([
35
+ register_prefix(
36
36
  'MP\d+', '\d+ST\d+(x|\*)\d+',
37
37
  'AFF', 'IDT', 'AFV', 'IDV'
38
- ])
38
+ )
39
39
 
40
40
  def initialize(command)
41
41
  super(command)
@@ -15,7 +15,7 @@ module BCDice
15
15
  # ダイスボットの使い方
16
16
  HELP_MESSAGE = "・SW レーティング表 (Kx[c]+m$f) (x:キー, c:クリティカル値, m:ボーナス, f:出目修正)\n"
17
17
 
18
- register_prefix(['H?K\d+.*'])
18
+ register_prefix('H?K\d+.*')
19
19
 
20
20
  def initialize(command)
21
21
  super(command)
@@ -31,8 +31,7 @@ module BCDice
31
31
  # @param [String] string 受信したメッセージ
32
32
  # @return [String]
33
33
  def replace_text(string)
34
- # TODO: Ruby 2.4以降では Regexp#match? を使うこと
35
- return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match(string)
34
+ return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string)
36
35
 
37
36
  string
38
37
  .gsub(/\[(\d+)\]/) { "c[#{Regexp.last_match(1)}]" }
@@ -45,17 +44,17 @@ module BCDice
45
44
  "cmCM"
46
45
  end
47
46
 
48
- def check_2D6(total, dice_total, _dice_list, cmp_op, target)
47
+ def result_2d6(total, dice_total, _dice_list, cmp_op, target)
49
48
  if dice_total >= 12
50
- "自動的成功"
49
+ Result.critical("自動的成功")
51
50
  elsif dice_total <= 2
52
- "自動的失敗"
51
+ Result.fumble("自動的失敗")
53
52
  elsif cmp_op != :>= || target == "?"
54
- ''
53
+ nil
55
54
  elsif total >= target
56
- "成功"
55
+ Result.success("成功")
57
56
  else
58
- "失敗"
57
+ Result.failure("失敗")
59
58
  end
60
59
  end
61
60
 
@@ -65,7 +65,7 @@ module BCDice
65
65
   絡み効果表を出すことができます。
66
66
  INFO_MESSAGE_TEXT
67
67
 
68
- register_prefix(['H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT'])
68
+ register_prefix('H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT')
69
69
 
70
70
  # 超越判定のノード
71
71
  class TranscendentTest
@@ -131,8 +131,7 @@ module BCDice
131
131
  # 出目のグループまたはその配列
132
132
  # @return [Integer]
133
133
  def sum_of_dice(value_groups)
134
- # TODO: Ruby 2.4以降では Array#sum が使える
135
- value_groups.flatten.reduce(0, &:+)
134
+ value_groups.flatten.sum
136
135
  end
137
136
 
138
137
  # ダイス部分の文字列を返す
@@ -68,14 +68,13 @@ module BCDice
68
68
   絡み効果表を出すことができます。
69
69
  INFO_MESSAGE_TEXT
70
70
 
71
- register_prefix(['H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT'])
71
+ register_prefix('H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT')
72
72
 
73
73
  # コマンド実行前にメッセージを置換する
74
74
  # @param [String] string 受信したメッセージ
75
75
  # @return [String]
76
76
  def replace_text(string)
77
- # TODO: Ruby 2.4以降では Regexp#match? を使うこと
78
- return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match(string)
77
+ return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string)
79
78
 
80
79
  super(string).gsub(/#([-+]?\d+)/) do
81
80
  modifier = Regexp.last_match(1).to_i
@@ -30,7 +30,7 @@ module BCDice
30
30
  ・OP3@12 → ダイス合計+3の達成値&クリティカル、判定の成否を表示。
31
31
  MESSAGETEXT
32
32
 
33
- register_prefix(['(TS|OP)(\d+)?([\+\-]\d)*(\@\d+)?'])
33
+ register_prefix('(TS|OP)(\d+)?([\+\-]\d)*(\@\d+)?')
34
34
 
35
35
  def eval_game_system_specific_command(command)
36
36
  output =
@@ -26,7 +26,7 @@ module BCDice
26
26
  @sort_add_dice = true
27
27
  end
28
28
 
29
- register_prefix(['\d+D6.*'])
29
+ register_prefix('\d+D6.*')
30
30
 
31
31
  def eval_game_system_specific_command(command)
32
32
  parser = CommandParser.new(/^\d+D6$/)
@@ -24,9 +24,9 @@ module BCDice
24
24
  MESSAGETEXT
25
25
 
26
26
  # ダイスボットで使用するコマンドを配列で列挙する
27
- register_prefix([
27
+ register_prefix(
28
28
  'OP', 'TB', 'TK?\(\d+\)'
29
- ])
29
+ )
30
30
 
31
31
  def eval_game_system_specific_command(command)
32
32
  output =
@@ -4,7 +4,7 @@ module BCDice
4
4
  module GameSystem
5
5
  class Torg < Base
6
6
  # ゲームシステムの識別子
7
- ID = 'TORG'
7
+ ID = 'Torg'
8
8
 
9
9
  # ゲームシステム名
10
10
  NAME = 'トーグ'
@@ -28,7 +28,7 @@ module BCDice
28
28
   ・ボーナス表「BTx+y or BONUSx+y or TOTALx+y」 xは数値, yは技能基本値
29
29
  INFO_MESSAGE_TEXT
30
30
 
31
- register_prefix(['TG.*', '1R20.*', 'RT.*', 'Result.*', 'IT.*', 'Initimidate.*', 'TT.*', 'Taunt.*', 'Trick.*', 'CT.*', 'MT.*', 'Maneuver.*', 'ODT.*', 'ords.*', 'odamage.*', 'DT.*', 'damage.*', 'BT.*', 'bonus.*', 'total.*'])
31
+ register_prefix('TG.*', '1R20.*', 'RT.*', 'Result.*', 'IT.*', 'Initimidate.*', 'TT.*', 'Taunt.*', 'Trick.*', 'CT.*', 'MT.*', 'Maneuver.*', 'ODT.*', 'ords.*', 'odamage.*', 'DT.*', 'damage.*', 'BT.*', 'bonus.*', 'total.*')
32
32
 
33
33
  def replace_text(string)
34
34
  string = string.gsub(/Result/i, 'RT')
@@ -6,7 +6,7 @@ module BCDice
6
6
  module GameSystem
7
7
  class Torg1_5 < Torg
8
8
  # ゲームシステムの識別子
9
- ID = 'TORG1.5'
9
+ ID = 'Torg1.5'
10
10
 
11
11
  # ゲームシステム名
12
12
  NAME = 'トーグ1.5版'
@@ -41,7 +41,7 @@ module BCDice
41
41
   ・ダメージ結果表「DTx or DAMAGEx」
42
42
   ・ロールボーナス表「BTx+y or BONUSx+y or TOTALx+y」 xは数値, yは技能基本値
43
43
  INFO_MESSAGE_TEXT
44
- register_prefix(['TE.*', 'UP.*', 'POS.*', '\d+BD.*', 'TG.*', 'RT.*', 'Result.*', 'DT.*', 'damage.*', 'BT.*', 'bonus.*', 'total.*', '1R20.*'])
44
+ register_prefix('TE.*', 'UP.*', 'POS.*', '\d+BD.*', 'TG.*', 'RT.*', 'Result.*', 'DT.*', 'damage.*', 'BT.*', 'bonus.*', 'total.*', '1R20.*')
45
45
  def initialize(command)
46
46
  super(command)
47
47
  end
@@ -33,7 +33,7 @@ module BCDice
33
33
 
34
34
  MESSAGETEXT
35
35
 
36
- register_prefix(['(\d+)DM\d+(\+|\-)?\d*', '(\d+)DM(\+|\-)?\d*', 'TR(\d+)<=(\d+)(\+|\-)?\d*', 'TR<=(\d+)(\+|\-)?\d*', 'TR(\+|\-)?(\d+)<=(\d+)(\+|\-)?\d*', 'TRNAME'])
36
+ register_prefix('(\d+)DM\d+(\+|\-)?\d*', '(\d+)DM(\+|\-)?\d*', 'TR(\d+)<=(\d+)(\+|\-)?\d*', 'TR<=(\d+)(\+|\-)?\d*', 'TR(\+|\-)?(\d+)<=(\d+)(\+|\-)?\d*', 'TRNAME')
37
37
 
38
38
  def eval_game_system_specific_command(command) # スパゲッティなコードだけど許して!!! → 絶対に許さない。全力でリファクタリングした。
39
39
  debug("eval_game_system_specific_command command", command)
@@ -30,7 +30,7 @@ module BCDice
30
30
   下から2番目の出目をずらした分だけ合計にマイナス修正を追加して表示します。
31
31
  INFO_MESSAGE_TEXT
32
32
 
33
- register_prefix(['\d+H?BS.*', '\d+R6.*', '\d+D\d+.+', '\dD6.*'])
33
+ register_prefix('\d+H?BS.*', '\d+R6.*', '\d+D\d+.+', '\dD6.*')
34
34
 
35
35
  def initialize(command)
36
36
  super(command)
@@ -43,7 +43,6 @@ module BCDice
43
43
  def initialize(command)
44
44
  super(command)
45
45
 
46
- @enabled_d66 = true
47
46
  @d66_sort_type = D66SortType::NO_SORT
48
47
  @sort_add_dice = true
49
48
  end
@@ -521,7 +520,7 @@ module BCDice
521
520
  )
522
521
  }.freeze
523
522
 
524
- register_prefix(['2D6.*'] + TABLES.keys)
523
+ register_prefix('2D6.*', TABLES.keys)
525
524
  end
526
525
  end
527
526
  end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice"
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class UnsungDuet < Base
8
+ ID = "UnsungDuet"
9
+ NAME = "アンサング・デュエット"
10
+ SORT_KEY = "あんさんくてゆえつと"
11
+
12
+ HELP_MESSAGE = <<~MESSAGETEXT
13
+ ■ シフター用判定 (shifter, UDS)
14
+ 1D10をダイスロールして判定を行います。
15
+ 例) shifter, UDS, shifter>=5, shifter+1>=6
16
+
17
+ ■ バインダー用判定 (binder, UDB)
18
+ 2D6をダイスロールして判定を行います。
19
+ 例) binder, UDB, binder>=5, binder+1>=6
20
+
21
+ ■ 変異表
22
+ ・外傷 (HIN, HInjury)
23
+ ・体調の変化 (HPH, HPhysical)
24
+ ・恐怖 (HFE, HFear)
25
+ ・幻想化 (HFA, HFantasy)
26
+ ・精神 (HMI, HMind)
27
+ ・そのほか (HOT, HOther)
28
+ MESSAGETEXT
29
+
30
+ ALIAS_1D10 = ["shifter", "UDS"].freeze
31
+ ALIAS_2D6 = ["binder", "UDB"].freeze
32
+
33
+ SHIFTER_ALIAS_REG = /^#{ALIAS_1D10.join('|')}/i.freeze
34
+ BINDER_ALIAS_REG = /^#{ALIAS_2D6.join('|')}/i.freeze
35
+
36
+ register_prefix(ALIAS_1D10, ALIAS_2D6)
37
+
38
+ def eval_game_system_specific_command(command)
39
+ command = ALIAS[command] || command
40
+
41
+ roll_replaced_command_if_match(command, SHIFTER_ALIAS_REG, "1D10") ||
42
+ roll_replaced_command_if_match(command, BINDER_ALIAS_REG, "2D6") ||
43
+ roll_tables(command, TABLES)
44
+ end
45
+
46
+ def roll_replaced_command_if_match(command, regexp, dist)
47
+ if command.match?(regexp)
48
+ CommonCommand::AddDice.eval(command.sub(regexp, dist), self, @randomizer)
49
+ end
50
+ end
51
+
52
+ ALIAS = {
53
+ "HInjury" => "HIN",
54
+ "HPhysical" => "HPH",
55
+ "HFear" => "HFE",
56
+ "HFantasy" => "HFA",
57
+ "HMind" => "HMI",
58
+ "HOther" => "HOT",
59
+ }.transform_keys(&:upcase)
60
+
61
+ TABLES = {
62
+ "HIN" => DiceTable::Table.new(
63
+ "変異表:外傷",
64
+ "1D6",
65
+ [
66
+ "顔の傷 → 顔にできた傷。じわりと血がにじむ",
67
+ "大きな怪我 → 早く手当てをしないと命に関わる",
68
+ "痛みのない傷 → 大きな傷なのに、なぜか痛くない",
69
+ "喪失 → 身体のどこかが消えてしまった",
70
+ "文字のような傷跡 → 読めない文字のような傷",
71
+ "模様を描くアザ → 模様のような、身体にできたアザ",
72
+ ]
73
+ ),
74
+ "HPH" => DiceTable::Table.new(
75
+ "変異表:体調の変化",
76
+ "1D6",
77
+ [
78
+ "視界がぼやける → 目の焦点が合わない",
79
+ "耳鳴り → ずっと甲高い音が鳴り続けている気がする",
80
+ "異様な寒気 → 凍えそうなほどに寒く感じる",
81
+ "発汗 → 暑いわけでもないのに、汗がだらだらと",
82
+ "幻覚 → それが本物か幻か、区別がつかない",
83
+ "走馬灯 → 過去のことを次々と思い出してしまう",
84
+ ]
85
+ ),
86
+ "HFE" => DiceTable::Table.new(
87
+ "変異表:恐怖",
88
+ "1D6",
89
+ [
90
+ "不安 → 漠然とした不安が心を蝕む",
91
+ "狭い場所が怖い → 狭い場所に入りたくない",
92
+ "震えが止まらない → どうしても落ち着かない",
93
+ "物音が怖い → ほんの小さな物音にも怯えてしまう",
94
+ "暗い場所が怖い → 灯りのない場所がひどく恐ろしい",
95
+ "誰かがついてくる → 誰かが後ろにいる気がする……",
96
+ ]
97
+ ),
98
+ "HFA" => DiceTable::Table.new(
99
+ "変異表:幻想化",
100
+ "1D6",
101
+ [
102
+ "硝子化 → 身体の一部がガラスのように透明に",
103
+ "羽毛化 → 身体のどこかから羽毛が生えてくる",
104
+ "植物化 → ツタや葉が身体から生えてくる",
105
+ "動物の瞳 → 瞳の形が動物のそれに変わってしまう",
106
+ "有角化 → 額や側頭部から角が生えてくる",
107
+ "陶器化 → 皮膚が陶器のようなものに変わっていく",
108
+ ]
109
+ ),
110
+ "HMI" => DiceTable::Table.new(
111
+ "変異表:精神",
112
+ "1D6",
113
+ [
114
+ "記憶の混乱 → ここはどこ、どうしてこんなところに?",
115
+ "幼少期の記憶 → 口調や態度が幼くなってしまう",
116
+ "素直 → 思ったことを全部言ってしまう",
117
+ "蛮勇 → パートナーを守るために無茶ばかりする",
118
+ "疑心暗鬼 → 何もかもが悪い方向にしか考えられない",
119
+ "食べちゃいたい → パートナーをかじりたくなる",
120
+ ]
121
+ ),
122
+ "HOT" => DiceTable::Table.new(
123
+ "変異表:そのほか",
124
+ "1D6",
125
+ [
126
+ "影絵化 → 身体の一部が影のようになる",
127
+ "水槽化 → 身体の一部が水槽のようなものになる",
128
+ "涙が止まらない → なぜか涙が流れ続ける",
129
+ "鉤爪 → 手や足が、獣のような鉤爪になる",
130
+ "未来視 → 未来が見えてしまう。本当かどうかは不明",
131
+ "帰りたくない → 現実に帰りたくないと微かに思う",
132
+ ]
133
+ ),
134
+ }.freeze
135
+
136
+ register_prefix(ALIAS.keys, TABLES.keys)
137
+ end
138
+ end
139
+ end
@@ -25,7 +25,7 @@ module BCDice
25
25
  例)3UK@5 :龍のダイス「月」でクリティカルコール宣言したサイコロ3個の行為判定
26
26
  MESSAGETEXT
27
27
 
28
- register_prefix(['\d*UK[@\d]*.*'])
28
+ register_prefix('\d*UK[@\d]*.*')
29
29
 
30
30
  def initialize(command)
31
31
  super(command)
@@ -41,7 +41,7 @@ module BCDice
41
41
  NOT_CHECK_SUCCESS = -1 # 判定成功にかかわるチェックを行わない(判定失敗に関わるチェックは行う)
42
42
 
43
43
  # ダイスボットで使用するコマンドを配列で列挙する
44
- register_prefix(['\d*VMF.*'])
44
+ register_prefix('\d*VMF.*')
45
45
 
46
46
  def eval_game_system_specific_command(command)
47
47
  m = /\A(\d+)?(VMF)(\d+)(\+(\d+))?/.match(command)
@@ -47,12 +47,11 @@ module BCDice
47
47
  ・改良種表      IS
48
48
  MESSAGETEXT
49
49
 
50
- register_prefix(['\\d+VBS(>=\\d+)?', '\\d+VF', '\\d+VM', '\\d+VG', 'PJ[VA]?', 'PQ[VA]?', 'AC', 'MM([IAD]|V[VA]?)', 'F[LRWGBCS]', 'IP[VA]?', 'EP[VA]?\\d?', 'MP', 'IS'])
50
+ register_prefix('\\d+VBS(>=\\d+)?', '\\d+VF', '\\d+VM', '\\d+VG', 'PJ[VA]?', 'PQ[VA]?', 'AC', 'MM([IAD]|V[VA]?)', 'F[LRWGBCS]', 'IP[VA]?', 'EP[VA]?\\d?', 'MP', 'IS')
51
51
 
52
52
  def initialize(command)
53
53
  super(command)
54
54
 
55
- @enabled_d66 = true
56
55
  @d66_sort_type = D66SortType::NO_SORT # D66あり。ただし、現行ルールにある6x6の表については別のコマンドを用意
57
56
  @round_type = RoundType::CEIL # 端数は切り上げ
58
57
  end
@@ -26,7 +26,7 @@ module BCDice
26
26
   例)wh60  wh43@4W  WH65@
27
27
  INFO_MESSAGE_TEXT
28
28
 
29
- register_prefix(['WH.*'])
29
+ register_prefix('WH.*')
30
30
 
31
31
  def initialize(command)
32
32
  super(command)
@@ -0,0 +1,329 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Warhammer4 < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'Warhammer4'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'ウォーハンマーRPG第4版'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'うおおはんまあ4'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
+ ■ クリティカル表 (whctH, whctA, whctB, whctL, whctHU, whctAU, whctBU, whctLU)
18
+ "WH部位 頑健ボーナス以下フラグ"の形で指定します。
19
+ 部位は「H(頭部)」「A(腕)」「B(胴体)」「L(足)」の4カ所です。
20
+ 頑健ボーナスフラグは頑健ボーナス以下のダメージの時にUをつけます。
21
+ 例)whH whAU WHL
22
+
23
+ ■ 命中部位表 (WHLT)
24
+ 命中部位をランダムに決定します。(クリティカル用)
25
+
26
+ ■ やっちまった!表 (WHFT)
27
+  やっちまった!表をロールして、結果を表示します。
28
+
29
+ ■ 命中判定 (WHx)
30
+ "WH(命中値)"の形で指定します。
31
+ 命中判定を行って、命中してクリティカルでなければ部位も表示します。
32
+ 例)wh60  wh(43-20)
33
+ INFO_MESSAGE_TEXT
34
+
35
+ register_prefix('WH')
36
+
37
+ def initialize(command)
38
+ super(command)
39
+
40
+ @round_type = RoundType::CEIL
41
+ end
42
+
43
+ def eval_game_system_specific_command(command)
44
+ roll_critical_table(command) || roll_attack(command) || roll_tables(command, TABLES)
45
+ end
46
+
47
+ def check_1D100(total, _dice_total, cmp_op, target)
48
+ return '' if target == '?'
49
+ return '' unless cmp_op == :<=
50
+
51
+ t10 = total / 10
52
+ d10 = target / 10
53
+ sl = d10 - t10
54
+
55
+ if total <= 5 && sl < 1
56
+ # 自動成功時のSLは最低でも1
57
+ sl = 1
58
+ elsif total >= 96 && sl > -1
59
+ # 自動失敗時のSLは最大でも-1
60
+ sl = -1
61
+ end
62
+
63
+ result =
64
+ if total <= 5
65
+ "自動成功"
66
+ elsif total >= 96
67
+ "自動失敗"
68
+ elsif total <= target
69
+ "成功"
70
+ else
71
+ "失敗"
72
+ end
73
+
74
+ sl_text = format("(SL%+d)", sl)
75
+
76
+ " > #{result}#{sl_text} > #{result_detail(sl, total, target)}"
77
+ end
78
+
79
+ private
80
+
81
+ def result_detail(sl, total, target)
82
+ if sl == 0
83
+ if total <= 5
84
+ '小成功'
85
+ elsif total >= 96
86
+ '小失敗'
87
+ elsif total <= target
88
+ '小成功'
89
+ else
90
+ '小失敗'
91
+ end
92
+ elsif sl >= 6
93
+ '超大成功'
94
+ elsif sl >= 4
95
+ '大成功'
96
+ elsif sl >= 2
97
+ '成功'
98
+ elsif sl > 0
99
+ '小成功'
100
+ elsif sl >= -1
101
+ '小失敗'
102
+ elsif sl >= -3
103
+ '失敗'
104
+ elsif sl >= -5
105
+ '大失敗'
106
+ else # sl <= -6
107
+ '超大失敗'
108
+ end
109
+ end
110
+
111
+ # クリティカル表
112
+ def roll_critical_table(command)
113
+ m = /^WHCT([HABTL])(U)?$/.match(command)
114
+ return nil unless m
115
+
116
+ part = m[1]
117
+ part = "B" if part == "T"
118
+
119
+ under_ganken_bonus = !m[2].nil?
120
+
121
+ CRITICAL_TABLES[part].roll(@randomizer, under_ganken_bonus)
122
+ end
123
+
124
+ class CriticalTable
125
+ def initialize(name, items)
126
+ @name = name
127
+ @items = items
128
+ end
129
+
130
+ def roll(randomizer, under_ganken_bonus)
131
+ dice = randomizer.roll_once(100)
132
+ if under_ganken_bonus
133
+ dice = (dice - 20).clamp(1, 100)
134
+ end
135
+
136
+ chosen = @items.find { |key, _| key >= dice }[1]
137
+
138
+ "#{@name}(#{dice}) > #{chosen}"
139
+ end
140
+ end
141
+
142
+ CRITICAL_TABLES = {
143
+ "H" => CriticalTable.new(
144
+ "頭部CT表",
145
+ [
146
+ [10, '勲章となる傷:耐久値-1:「出血状態」1つを得る。社交系テストSL+1(累積なし)。'],
147
+ [20, '小さな裂傷:耐久値-1:「出血状態」1つを得る。'],
148
+ [25, '眼窩の負傷:耐久値-1:「目がくらんだ状態」1つを得る。'],
149
+ [30, '耳朶への強打:耐久値-1:「耳鳴り状態」1つを得る。'],
150
+ [35, '朦朧化打撃:耐久値-2:「朦朧状態」1つを得る。'],
151
+ [40, '眼の周りの青あざ:耐久値-2:「目がくらんだ状態」2つを得る。'],
152
+ [45, '耳朶の裂傷:耐久値-2:「出血状態」2つに加えて、「耳鳴り状態」1つを得る。'],
153
+ [50, '額への一打:耐久値-2:「出血状態」2つに加えて「目がくらんだ状態」1つを得る。なお後者は「出血状態」を取り除いた後でなければ取り除けない。'],
154
+ [55, '顎骨折:耐久値-3:「朦朧状態」2つを得る。さらに「骨折(軽度)」の負傷を得る。'],
155
+ [60, '眼窩の大怪我:耐久値-3:「出血状態」2つを得る。さらに「目がくらんだ状態」1つも得て、こちらは「治療行為」を受けない限り回復できない。'],
156
+ [65, '耳朶の大怪我:耐久値-3:片耳の聴力を失う。聴覚に関するテストに-20。この効果をもう一度受けた場合、永続的な聴覚喪失者となる。これは魔法でしか治療できない。'],
157
+ [70, '鼻砕き:耐久値-3:「出血状態」2つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したら「朦朧状態」1つも得る。社交系テストに+1/-1。'],
158
+ [75, '顎粉砕:耐久値-4:「朦朧状態」3つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したら「気絶状態」を得る。「骨折(重度)」の負傷を得る。'],
159
+ [80, '脳震盪打撃:耐久値-4:「出血状態」2つと「耳鳴り状態」1つに加えて1d10の「朦朧状態」を得る。さらに1d10日間継続する「疲労状態」1つも得る。この「疲労状態」継続中に頭部への「致命的負傷」を再度得たなら、「普通(+20)」の〈肉体抵抗〉テストを行い、失敗したなら追加で「気絶状態」になる。'],
160
+ [85, '口粉砕:耐久値-4:「出血状態」2つを得る。1d10本の歯が失われる。「身体欠損(容易)」を被る。'],
161
+ [90, '耳が屑肉に:耐久値-4:「耳鳴り状態」3つに加えて「出血状態」2つを得る。片耳の機能を失う。「身体欠損(普通)」を被る。'],
162
+ [93, '眼球破裂:耐久値-5:「目がくらんだ状態」3つと、「出血状態」2つ、「朦朧状態」1つを得る。片目の機能を失う。「身体欠損(難しい)」を被る。'],
163
+ [96, '顔が化け物のように:耐久値-5:「出血状態」3つ「目がくらんだ状態」3つ、「朦朧状態」2つを得る。片目の機能を失い、鼻梁も失う。「身体欠損(多難)」を被る。'],
164
+ [99, '顎が屑肉に:耐久値-5:「出血状態」4つと「朦朧状態」3つを得る。「超多難(-30)」な〈肉体抵抗〉テストを行い、失敗したら「気絶状態」になる。「骨折(重度)」の負傷を得て、舌と1d10本の歯を失う。「身体欠損(多難)」を被る。'],
165
+ [100, '斬首刑さながらに:即死:'],
166
+ ]
167
+ ),
168
+ "A" => CriticalTable.new(
169
+ "腕部CT表",
170
+ [
171
+ [10, '腕痺れ:耐久値-1:手に持っているものを落としてしまう。'],
172
+ [20, '小さな裂傷:耐久値-1:「出血状態」1つを得る。'],
173
+ [25, '捻挫:耐久値-1:「筋断裂(軽度)」の負傷を得る。'],
174
+ [30, 'ひどい腕痺れ:耐久値-2:手に持っているものを落としてしまい、その腕は1d10-【頑健力】ボーナスのラウンドに渡って使えなくなる。'],
175
+ [35, '筋断裂:耐久値-2:「出血状態」1つと、「筋断裂(軽度)」の負傷を得る。'],
176
+ [40, '手の出血:耐久値-2:「出血状態」1つを得る。その手で何かを握る「アクション」を行う場合、先立って「普通(+20)」の【器用度】テストを行い、失敗したら取り落としてしまう。'],
177
+ [45, '肩の捻挫:耐久値-2:手に持っているものを落としてしまい、その腕は1d10ラウンドに渡って使えなくなる。'],
178
+ [50, '大きな傷口:耐久値-3:「出血状態」2つを得る。傷口を縫う「手術」を受ける前に同じ腕にダメージを受けた場合、傷口が開き「出血状態」1つを追加で得る。'],
179
+ [55, '単純骨折:耐久値-3:手に持っているものを落としてしまい、「骨折(軽度)」の負傷を得る。「難しい(-10)」〈肉体抵抗〉テストを行い、失敗したなら「朦朧状態」1つを得る。'],
180
+ [60, '靱帯断裂:耐久値-3:手に持っているものを落としてしまい、「筋断裂(重度)」の負傷を得る。'],
181
+ [65, '深手:耐久値-3:「出血状態」2つを得る。「朦朧状態」1つを得て、「筋断裂(軽度)」の負傷を得る。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「気絶状態」になる。'],
182
+ [70, '動脈破損:耐久値-4:「出血状態」4つを得る。「手術」を受ける前に同じ腕にダメージを受けるたびに「出血状態」2つを得る。'],
183
+ [75, '肘粉砕:耐久値-4:手に持っているものを落としてしまい、「筋断裂(重度)」の負傷を得る。'],
184
+ [80, '肩の脱臼:耐久値-4:「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「朦朧状態」1つを得て「伏せ状態」になる。手に持っているものを落としてしまう。その腕を使うことはできず、欠損したものとして扱う。さらに「治療行為」を受けるまでの間「朦朧状態」1つを得る。'],
185
+ [85, '指切断:耐久値-4:「身体欠損(普通)」を被る。「出血状態」1つを得る。'],
186
+ [90, '手の半切断:耐久値-5:指一本を失い、「身体欠損(多難)」を被る。「出血状態」2つと「朦朧状態」1つを得る。君が「治療行為」を受けるまでの以降の各ラウンドに指を一本ずつ失う。すべての指を失ったら、その手の機能を失い「身体欠損(難しい)」を得る。'],
187
+ [93, '力こぶがズタズタに:耐久値-5:手に持っていたものを落とすとともに「筋断裂(重度)」の負傷を得て、「出血状態」2つと「朦朧状態」1つを得る。'],
188
+ [96, '片手が屑肉同然に:耐久値-5:その手の機能を失い、「身体欠損(多難)」を被る。「出血状態」2つを得る。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「気絶状態」になる。'],
189
+ [99, '靱帯断裂:耐久値-5:腕は無用の長物と化す―「身体欠損(超多難)」を被る。「出血状態」3つ、「朦朧状態」1つを得て、「伏せ状態」になる。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「気絶状態」になる。'],
190
+ [100, '残酷な腕の喪失:即死:'],
191
+ ]
192
+ ),
193
+ "B" => CriticalTable.new(
194
+ "胴体CT表",
195
+ [
196
+ [10, 'ただのかすり傷だって!:耐久値-1:「出血状態」1つを得る。'],
197
+ [20, 'みぞおちへの一打:耐久値-1:「朦朧状態」1つを得る。「容易(+40)」な〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。'],
198
+ [25, '下腹部に直撃!:耐久値-1:「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「朦朧状態」3つを得る。'],
199
+ [30, '背中を捻じる:耐久値-1:「筋断裂(軽度)」の負傷を得る。'],
200
+ [35, '息ができない:耐久値-2:「朦朧状態」1つを得る。「普通(+20)」の〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。また、1d10ラウンドに渡って「移動力」が半分になる。'],
201
+ [40, '肋骨に青あざ:耐久値-2:1d10日間に渡って【敏捷力】に関連するテストに-10。'],
202
+ [45, '鎖骨捻じれ:耐久値-2:左右どちらの鎖骨かランダムに決定する。そちらの手に持っている物を落としてしまい、1d10ラウンドに渡ってその腕は使用できない。'],
203
+ [50, '裂傷:耐久値-2:「出血状態」2つを得る。'],
204
+ [55, '肋骨にひびが:耐久値-3:「朦朧状態」1つを得る。また、「骨折(軽度)」の負傷を得る。'],
205
+ [60, '大きな傷口:耐久値-3:「出血状態」3つを得る。「手術」を受けるまでの間、胴体に命中を受けるたびに追加で1つの「出血状態」を得る。'],
206
+ [65, '激痛を伴う裂傷:耐久値-3:「出血状態」2つと「朦朧状態」1つを得る。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「気絶状態」になる。またSL+4以上でテストに成功していない限り、金切り声を上げてしまう。'],
207
+ [70, '動脈損傷:耐久値-3:「出血状態」4つを得る。「手術」を受けるまでの間、胴体に攻撃を受けるたびに追加で2つの「出血状態」を得る。'],
208
+ [75, '背筋断裂:耐久値-4:「筋断裂(重度)」の負傷を得る。'],
209
+ [80, '股関節骨折:耐久値-4:「朦朧状態」1つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」にもなる。「骨折(軽度)」の負傷を得る。'],
210
+ [85, '胸郭の大怪我:耐久値-4:「出血状態」4つを得る。「手術」を受けるまでの間、胴体に命中を受けるたびに追加で2つの「出血状態」を得る。'],
211
+ [90, '内臓の損傷:耐久値-4:「膿み傷」に罹患し、「出血状態」2つを得る。'],
212
+ [93, '胸郭粉砕:耐久値-5:「朦朧状態」1つを得る。これは「治療行為」を受けない限り取り除くことは出来ない。さらに「骨折(重度)」の負傷を得る。'],
213
+ [96, '鎖骨粉砕:耐久値-5:「気絶状態」になる。これは「治療行為」を受けない限り取り除くことは出来ない。さらに「骨折(重度)」の負傷を得る。'],
214
+ [99, '内臓出血:耐久値-5:「出血状態」1つを得る。これは「手術」を受けない限り取り除くことは出来ない。さらに「血液腐れ病」に罹患する。'],
215
+ [100, '胴部両断:即死:'],
216
+ ]
217
+ ),
218
+ "L" => CriticalTable.new(
219
+ "脚部CT表",
220
+ [
221
+ [10, '爪先をぶつける:耐久値-1:「普通(+20)」の〈肉体抵抗〉テストを行い、失敗したなら次のターンの終了時まで【敏捷力】に関するテストに-10。'],
222
+ [20, '足首の捻挫:耐久値-1:以降1d10ラウンドに渡って【敏捷力】に関連するテストに-10。'],
223
+ [25, '小さな裂傷:耐久値-1:「出血状態」1つを得る。'],
224
+ [30, '足がかりを失う:耐久値-1:「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。'],
225
+ [35, '太腿への打撃:耐久値-2:「出血状態」1つを得て「普通(+20)」の〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。'],
226
+ [40, '足首の筋断裂:耐久値-2:「筋断裂(軽度)」の負傷を得る。'],
227
+ [45, '膝の捻挫:耐久値-2:以降1d10ラウンドに渡って【敏捷力】に関連するテストに-20。'],
228
+ [50, '爪先のひどい裂傷:耐久値-2:「出血状態」1つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したなら片方の爪先を失う―「身体欠損(普通)」を被る。'],
229
+ [55, 'ひどい裂傷:耐久値-3:「出血状態」2つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。'],
230
+ [60, '膝のひどい捻挫:耐久値-3:「筋断裂(重度)」の負傷を得る。'],
231
+ [65, '脚への痛打:耐久値-3:「伏せ状態」に加えて「出血状態」2つを得て、「骨折(軽度)」の負傷を得る。さらに「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「朦朧状態」1つを追加で得る。'],
232
+ [70, '太腿への深手:耐久値-3:「出血状態」3つを得る。「手強い(+0)」〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」になる。「手術」を受けるまでの間、この脚に命中を受けるたびに、追加で1つの「出血状態」を得る。'],
233
+ [75, '靱帯断裂:耐久値-4:「伏せ状態」に加えて「朦朧状態」1つを得る。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「気絶状態」になる。君のその脚は使えなくなる。'],
234
+ [80, '脛への深手:耐久値-4:敵の武器が君の膝下に当たり、骨に食い込んで腱を切断する。「朦朧状態」1つを得て、「伏せ状態」になる。さらに「筋断裂(重度)」と「骨折(軽度)」の負傷を得る。'],
235
+ [85, '膝粉砕:耐久値-4:「出血状態」1つと「朦朧状態」1つを得ることに加えて、「伏せ状態」になる。「骨折(重度)」の負傷を得る。'],
236
+ [90, '膝関節脱臼:耐久値-4:「伏せ状態」になる。「多難(-20)」な〈肉体抵抗〉テストを行い、失敗したなら「朦朧状態」1つを得る。これは「治療行為」を受けない限り取り除くことができない。'],
237
+ [93, '脚粉砕:耐久値-5:「普通(+20)」の〈肉体抵抗〉テストを行い、失敗したなら「伏せ状態」を得て、足の指1本を失う。さら、SLが-1あるごとに追加で1つの足指を失う―「身体欠損(普通)」を被る。「出血状態」2つを得る。'],
238
+ [96, '足切断:耐久値-5:「身体欠損(多難)」を被る。「出血状態」3つと「朦朧状態」2つを得て「伏せ状態」になる。'],
239
+ [99, 'アキレス腱切断:耐久値-5:苦痛に金切り声を上げながら倒れる。「出血状態」2つと「朦朧状態」2つを得て「伏せ状態」になる。「身体欠損(超多難)」を被る。'],
240
+ [100, '骨盤粉砕:即死:'],
241
+ ]
242
+ ),
243
+ }.freeze
244
+
245
+ # 命中判定
246
+ def roll_attack(command)
247
+ m = /^WH(\d+)$/.match(command)
248
+ return nil unless m
249
+
250
+ target_number = m[1].to_i
251
+ total = @randomizer.roll_once(100)
252
+ result = check_1D100(total, total, :<=, target_number).delete_prefix(" > ")
253
+
254
+ sequence = [
255
+ "(#{command})",
256
+ total,
257
+ result,
258
+ additional_result(total, target_number),
259
+ ].compact
260
+
261
+ return sequence.join(" > ")
262
+ end
263
+
264
+ def additional_result(total, target_number)
265
+ tens, ones = split_d100(total)
266
+ result =
267
+ if (total > target_number) || (total > 95) # 自動失敗時のファンブル処理も
268
+ if ones == tens
269
+ "ファンブル"
270
+ end
271
+ elsif ones == tens
272
+ "クリティカル"
273
+ else
274
+ # 一の位と十の位を入れ替えて参照する
275
+ HIT_PARTS_TABLE.fetch(merge_d100(ones, tens)).content
276
+ end
277
+
278
+ result
279
+ end
280
+
281
+ def split_d100(dice)
282
+ if dice == 100
283
+ return 0, 0
284
+ else
285
+ return dice / 10, dice % 10
286
+ end
287
+ end
288
+
289
+ def merge_d100(tens, ones)
290
+ if tens == 0 && ones == 0
291
+ 100
292
+ else
293
+ tens * 10 + ones
294
+ end
295
+ end
296
+
297
+ HIT_PARTS_TABLE = DiceTable::RangeTable.new(
298
+ "命中部位表",
299
+ "1D100",
300
+ [
301
+ # [0, '二足'],
302
+ [1..9, '頭部'],
303
+ [10..24, '左腕(逆腕)'],
304
+ [25..44, '右腕(利腕)'],
305
+ [45..79, '胴体'],
306
+ [80..89, '左脚'],
307
+ [90..100, '右脚'],
308
+ ]
309
+ )
310
+
311
+ TABLES = {
312
+ "WHLT" => HIT_PARTS_TABLE,
313
+ "WHFT" => DiceTable::RangeTable.new(
314
+ "やっちまった!表",
315
+ "1D100",
316
+ [
317
+ [1..20, '君は自分の体の一部に当ててしまった。「耐久度」1点を失う。'],
318
+ [21..40, '君の武器が1ダメージを受ける。次のラウンドの行動順が一番最後になる。'],
319
+ [41..60, '君は身体動作の目算を誤る。次のラウンドのアクションに-10。'],
320
+ [61..70, '君はひどく躓きバランスを回復するのに手間取る。次の「移動」を失う。'],
321
+ [71..80, '君は武器を取り回しを誤る。次の「アクション」を失う。'],
322
+ [81..90, '君は筋を違えるか、足首をひねってしまう。「筋断裂(軽度)」の負傷を得る。「致命的負傷」としてカウントされる。'],
323
+ [91..100, '君は射程内のランダムな味方を攻撃してしまう。命中判定の出目の1の位をSLとして用いること。攻撃可能な味方が居ない場合は、自己を攻撃ししまい「朦朧状態」1つを得る。'],
324
+ ]
325
+ )
326
+ }.freeze
327
+ end
328
+ end
329
+ end