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
@@ -45,20 +45,16 @@ module BCDice
45
45
    強力でない呪文の場合 FCL/強力な呪文の場合 FCM
46
46
  INFO_MESSAGE_TEXT
47
47
 
48
- register_prefix(['CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR.*', 'BMR', 'BMS', 'FCL', 'FCM', 'PH', 'MA'])
48
+ register_prefix('CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR.*', 'BMR', 'BMS', 'FCL', 'FCM', 'PH', 'MA')
49
49
 
50
- def initialize(command)
51
- super(command)
52
-
53
- @bonus_dice_range = (-2..2)
54
- end
50
+ BONUS_DICE_RANGE = (-2..2).freeze
55
51
 
56
52
  def eval_game_system_specific_command(command)
57
53
  case command
58
54
  when /^CC/i
59
- return getCheckResult(command)
55
+ return skill_roll(command)
60
56
  when /^CBR/i
61
- return getCombineRoll(command)
57
+ return combine_roll(command)
62
58
  when /^FAR/i
63
59
  return getFullAutoResult(command)
64
60
  when /^BMR/i # 狂気の発作(リアルタイム)
@@ -80,6 +76,52 @@ module BCDice
80
76
 
81
77
  private
82
78
 
79
+ class ResultLevel
80
+ LEVEL = [
81
+ :fumble,
82
+ :failure,
83
+ :regular_success,
84
+ :hard_success,
85
+ :extreme_success,
86
+ :critical,
87
+ ].freeze
88
+
89
+ LEVEL_TO_S = {
90
+ critical: "クリティカル",
91
+ extreme_success: "イクストリーム成功",
92
+ hard_success: "ハード成功",
93
+ regular_success: "レギュラー成功",
94
+ fumble: "ファンブル",
95
+ failure: "失敗",
96
+ }.freeze
97
+
98
+ def initialize(level)
99
+ @level = level
100
+ @level_index = LEVEL.index(level)
101
+ raise ArgumentError unless @level_index
102
+ end
103
+
104
+ def success?
105
+ @level_index >= LEVEL.index(:regular_success)
106
+ end
107
+
108
+ def failure?
109
+ @level_index <= LEVEL.index(:failure)
110
+ end
111
+
112
+ def critical?
113
+ @level == :critical
114
+ end
115
+
116
+ def fumble?
117
+ @level == :fumble
118
+ end
119
+
120
+ def to_s
121
+ LEVEL_TO_S[@level]
122
+ end
123
+ end
124
+
83
125
  def roll_1d8_table(table_name, table)
84
126
  total_n = @randomizer.roll_once(8)
85
127
  index = total_n - 1
@@ -98,37 +140,44 @@ module BCDice
98
140
  return "#{table_name}(#{total_n}) > #{text}"
99
141
  end
100
142
 
101
- def getCheckResult(command)
102
- m = /^CC([-+]?\d+)?(<=(\d+))?/i.match(command)
143
+ def skill_roll(command)
144
+ m = /^CC([-+]?\d+)?(?:<=(\d+))?$/.match(command)
103
145
  unless m
104
146
  return nil
105
147
  end
106
148
 
107
- bonus_dice_count = m[1].to_i # ボーナス・ペナルティダイスの個数
108
- diff = m[3].to_i
109
- without_compare = m[2].nil? || diff <= 0
149
+ bonus_dice = m[1].to_i
150
+ difficulty = m[2].to_i
110
151
 
111
- if bonus_dice_count == 0 && diff <= 0
152
+ if bonus_dice == 0 && difficulty == 0
112
153
  dice = @randomizer.roll_once(100)
113
154
  return "1D100 > #{dice}"
114
155
  end
115
156
 
116
- unless @bonus_dice_range.include?(bonus_dice_count)
117
- return "エラー。ボーナス・ペナルティダイスの値は#{@bonus_dice_range.min}~#{@bonus_dice_range.max}です。"
157
+ unless BONUS_DICE_RANGE.include?(bonus_dice)
158
+ return "エラー。ボーナス・ペナルティダイスの値は#{BONUS_DICE_RANGE.min}~#{BONUS_DICE_RANGE.max}です。"
118
159
  end
119
160
 
120
- total, total_list = roll_with_bonus(bonus_dice_count)
161
+ total, total_list = roll_with_bonus(bonus_dice)
121
162
 
122
- if without_compare
123
- output = "(1D100) ボーナス・ペナルティダイス[#{bonus_dice_count}]"
124
- output += " > #{total_list.join(', ')} > #{total}"
125
- else
126
- result_text = getCheckResultText(total, diff)
127
- output = "(1D100<=#{diff}) ボーナス・ペナルティダイス[#{bonus_dice_count}]"
128
- output += " > #{total_list.join(', ')} > #{total} > #{result_text}"
129
- end
163
+ expr = difficulty.zero? ? "1D100" : "1D100<=#{difficulty}"
164
+ result = result_level(total, difficulty) unless difficulty.zero?
130
165
 
131
- return output
166
+ sequence = [
167
+ "(#{expr}) ボーナス・ペナルティダイス[#{bonus_dice}]",
168
+ total_list.join(", "),
169
+ total,
170
+ result,
171
+ ].compact
172
+
173
+ Result.new.tap do |r|
174
+ r.text = sequence.join(" > ")
175
+ if result
176
+ r.condition = result.success?
177
+ r.critical = result.critical?
178
+ r.fumble = result.fumble?
179
+ end
180
+ end
132
181
  end
133
182
 
134
183
  # 1D100の一の位用のダイスロール
@@ -163,58 +212,50 @@ module BCDice
163
212
  return dice, dice_list
164
213
  end
165
214
 
166
- def getCheckResultText(total, diff, fumbleable = false)
167
- if total <= diff
168
- return "クリティカル" if total == 1
169
- return "イクストリーム成功" if total <= (diff / 5)
170
- return "ハード成功" if total <= (diff / 2)
171
-
172
- return "レギュラー成功"
173
- end
174
-
175
- fumble_text = "ファンブル"
176
-
177
- return fumble_text if total == 100
178
-
179
- if total >= 96
180
- if diff < 50
181
- return fumble_text
182
- else
183
- return fumble_text if fumbleable
184
- end
215
+ def result_level(total, difficulty, fumbleable = false)
216
+ fumble = difficulty < 50 || fumbleable ? 96 : 100
217
+
218
+ if total == 1
219
+ ResultLevel.new(:critical)
220
+ elsif total <= (difficulty / 5)
221
+ ResultLevel.new(:extreme_success)
222
+ elsif total <= (difficulty / 2)
223
+ ResultLevel.new(:hard_success)
224
+ elsif total <= difficulty
225
+ ResultLevel.new(:regular_success)
226
+ elsif total >= fumble
227
+ ResultLevel.new(:fumble)
228
+ else
229
+ ResultLevel.new(:failure)
185
230
  end
186
-
187
- return "失敗"
188
231
  end
189
232
 
190
- def getCombineRoll(command)
191
- return nil unless /CBR\((\d+),(\d+)\)/i =~ command
233
+ def combine_roll(command)
234
+ m = /^CBR\((\d+),(\d+)\)$/.match(command)
235
+ return nil unless m
192
236
 
193
- diff_1 = Regexp.last_match(1).to_i
194
- diff_2 = Regexp.last_match(2).to_i
237
+ difficulty_1 = m[1].to_i
238
+ difficulty_2 = m[2].to_i
195
239
 
196
240
  total = @randomizer.roll_once(100)
197
241
 
198
- result_1 = getCheckResultText(total, diff_1)
199
- result_2 = getCheckResultText(total, diff_2)
200
-
201
- successList = ["クリティカル", "イクストリーム成功", "ハード成功", "レギュラー成功"]
202
-
203
- succesCount = 0
204
- succesCount += 1 if successList.include?(result_1)
205
- succesCount += 1 if successList.include?(result_2)
206
- debug("succesCount", succesCount)
242
+ result_1 = result_level(total, difficulty_1)
243
+ result_2 = result_level(total, difficulty_2)
207
244
 
208
245
  rank =
209
- if succesCount >= 2
246
+ if result_1.success? && result_2.success?
210
247
  "成功"
211
- elsif succesCount == 1
248
+ elsif result_1.success? || result_2.success?
212
249
  "部分的成功"
213
250
  else
214
251
  "失敗"
215
252
  end
216
253
 
217
- return "(1d100<=#{diff_1},#{diff_2}) > #{total}[#{result_1},#{result_2}] > #{rank}"
254
+ Result.new.tap do |r|
255
+ r.text = "(1d100<=#{difficulty_1},#{difficulty_2}) > #{total}[#{result_1},#{result_2}] > #{rank}"
256
+ r.success = result_1.success? && result_2.success?
257
+ r.failure = result_1.failure? && result_2.failure?
258
+ end
218
259
  end
219
260
 
220
261
  def getFullAutoResult(command)
@@ -261,8 +302,8 @@ module BCDice
261
302
  broken_number = broken_number.abs
262
303
  end
263
304
 
264
- unless @bonus_dice_range.include?(bonus_dice_count)
265
- return "エラー。ボーナス・ペナルティダイスの値は#{@bonus_dice_range.min}~#{@bonus_dice_range.max}です。"
305
+ unless BONUS_DICE_RANGE.include?(bonus_dice_count)
306
+ return "エラー。ボーナス・ペナルティダイスの値は#{BONUS_DICE_RANGE.min}~#{BONUS_DICE_RANGE.max}です。"
266
307
  end
267
308
 
268
309
  output += "ボーナス・ペナルティダイス[#{bonus_dice_count}]"
@@ -286,7 +327,7 @@ module BCDice
286
327
  output += getNextDifficultyMessage(more_difficulty)
287
328
 
288
329
  # ペナルティダイスを減らしながらロール用ループ
289
- while dice_num >= @bonus_dice_range.min
330
+ while dice_num >= BONUS_DICE_RANGE.min
290
331
 
291
332
  loopCount += 1
292
333
  hit_result, total, total_list = getHitResultInfos(dice_num, diff, more_difficulty)
@@ -349,7 +390,7 @@ module BCDice
349
390
  total, total_list = roll_with_bonus(dice_num)
350
391
 
351
392
  fumbleable = getFumbleable(more_difficulty)
352
- hit_result = getCheckResultText(total, diff, fumbleable)
393
+ hit_result = result_level(total, diff, fumbleable).to_s
353
394
 
354
395
  return hit_result, total, total_list
355
396
  end
@@ -35,7 +35,7 @@ module BCDice
35
35
  ・實時型 Short/總結型 Longer
36
36
  INFO_MESSAGE_TEXT
37
37
 
38
- register_prefix(['CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR\(\d+\)', 'FAR.*'])
38
+ register_prefix('CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR\(\d+\)', 'FAR.*')
39
39
 
40
40
  def initialize(command)
41
41
  super(command)
@@ -32,7 +32,7 @@ module BCDice
32
32
  예)FAR(25,70,98) FAR(50,80,98,-1)
33
33
  INFO_MESSAGE_TEXT
34
34
 
35
- register_prefix(['CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR\(\d+\)', 'FAR.*'])
35
+ register_prefix('CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR\(\d+\)', 'FAR.*')
36
36
 
37
37
  def initialize(command)
38
38
  super(command)
@@ -6,7 +6,7 @@ require 'bcdice/arithmetic_evaluator'
6
6
  module BCDice
7
7
  module GameSystem
8
8
  class CthulhuTech < Base
9
- register_prefix(['\d+D10.*'])
9
+ register_prefix('\d+D10.*')
10
10
 
11
11
  # ゲームシステムの識別子
12
12
  ID = 'CthulhuTech'
@@ -124,27 +124,21 @@ module BCDice
124
124
  def calculate_roll_result(sorted_dice_values)
125
125
  highest_single_roll = sorted_dice_values.last
126
126
 
127
+ sum_of_highest_set_of_multiples = sorted_dice_values
128
+ .group_by(&:itself)
129
+ .values
130
+ .map(&:sum)
131
+ .max
132
+
127
133
  candidates = [
128
134
  highest_single_roll,
129
- sum_of_highest_set_of_multiples(sorted_dice_values),
135
+ sum_of_highest_set_of_multiples,
130
136
  sum_of_largest_straight(sorted_dice_values)
131
137
  ]
132
138
 
133
139
  return candidates.max
134
140
  end
135
141
 
136
- # ゾロ目の和の最大値を求める
137
- # @param [Array<Integer>] dice_values 出目の配列
138
- # @return [Integer]
139
- def sum_of_highest_set_of_multiples(dice_values)
140
- dice_values.
141
- # TODO: Ruby 2.2以降では group_by(&:itself) が使える
142
- group_by { |i| i }.
143
- # TODO: Ruby 2.4以降では value_group.sum が使える
144
- map { |_, value_group| value_group.reduce(0, &:+) }
145
- .max
146
- end
147
-
148
142
  # ストレートの和の最大値を求める
149
143
  #
150
144
  # ストレートとは、昇順で3個以上連続した値のこと。
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bcdice/game_system/Cthulhu"
4
+
3
5
  module BCDice
4
6
  module GameSystem
5
- class Cthulhu_ChineseTraditional < Base
7
+ class Cthulhu_ChineseTraditional < Cthulhu
6
8
  # ゲームシステムの識別子
7
9
  ID = 'Cthulhu:ChineseTraditional'
8
10
 
@@ -44,199 +46,14 @@ module BCDice
44
46
  ・CCB(x) c=5、f=96
45
47
  同上
46
48
 
47
- ・瘋狂表
48
- ・短期瘋期 Short/長期瘋狂 Longer
49
-
50
49
  INFO_MESSAGE_TEXT
51
50
 
52
- register_prefix(['CC(B)?\(\d+\)', 'CC(B)?.*', 'RES(B)?.*', 'CBR(B)?\(\d+,\d+\)'])
53
-
54
- def initialize
55
- # $isDebug = true
56
- super
57
- @special_percentage = 20
58
- @critical_percentage = 1
59
- @fumble_percentage = 1
60
- end
61
-
62
- def eval_game_system_specific_command(command)
63
- case command
64
- when /CCB/i
65
- # 5%
66
- @critical_percentage = 5
67
- @fumble_percentage = 5
68
- return getCheckResult(command)
69
- when /CC/i
70
- # 1%
71
- @critical_percentage = 1
72
- @fumble_percentage = 1
73
- return getCheckResult(command)
74
- when /RESB/i
75
- # 5%
76
- @critical_percentage = 5
77
- @fumble_percentage = 5
78
- return getRegistResult(command)
79
- when /CBRB/i
80
- # 5%
81
- @critical_percentage = 5
82
- @fumble_percentage = 5
83
- return getCombineRoll(command)
84
- when /RES/i
85
- # 1%
86
- @critical_percentage = 1
87
- @fumble_percentage = 1
88
- return getRegistResult(command)
89
- when /CBR/i
90
- # 1%
91
- @critical_percentage = 1
92
- @fumble_percentage = 1
93
- return getCombineRoll(command)
94
- end
95
-
96
- return nil
97
- end
98
-
99
- def getCheckResult(command)
100
- broken_num = 0
101
- diff = 0
102
-
103
- if (m = /CC(B)?(\d+)<=(\d+)/i.match(command))
104
- # /\(\d+\)/の()はpattern-killerにカイシャクされる
105
- broken_num = m[2].to_i
106
- diff = m[3].to_i
107
- elsif (m = /CC(B)?<=(\d+)/i.match(command))
108
- diff = m[2].to_i
109
- end
110
-
111
- output = ""
112
-
113
- if diff > 0
114
- output = "(1D100<=#{diff})"
115
-
116
- if broken_num > 0
117
- output += " 故障率[#{broken_num}]"
118
- end
119
-
120
- total_n = @randomizer.roll_once(100)
121
-
122
- output += " > #{total_n}"
123
- output += " > #{getCheckResultText(total_n, diff, broken_num)}"
124
- else
125
- total_n = @randomizer.roll_once(100)
126
- output = "(1D100) > #{total_n}"
127
- end
128
-
129
- return output
130
- end
131
-
132
- def getCheckResultText(total_n, diff, broken_num = 0)
133
- result = ""
134
- diff_special = 0
135
- fumble = false
136
-
137
- if @special_percentage > 0
138
- # 需有special的數值設定才能做爆擊/大失敗的判定
139
- diff_special = (diff * @special_percentage / 100).floor
140
- if diff_special < 1
141
- diff_special = 1
142
- end
143
- end
144
-
145
- if (total_n <= diff) && (total_n < 100)
146
- result = "成功"
147
-
148
- if diff_special > 0
149
- if total_n <= @critical_percentage
150
- if total_n <= diff_special
151
- result = "決定性的成功/特殊"
152
- else
153
- result = "決定性的成功"
154
- end
155
- else
156
- if total_n <= diff_special
157
- result = "特殊"
158
- end
159
- end
160
- end
161
- else
162
- result = "失敗"
163
-
164
- if diff_special > 0
165
- if (total_n >= (101 - @fumble_percentage)) && (diff < 100)
166
- result = "致命性失敗"
167
- fumble = true
168
- end
169
- end
170
- end
171
-
172
- if broken_num > 0
173
- if total_n >= broken_num
174
- if fumble
175
- result += "/故障"
176
- else
177
- result = "故障"
178
- end
179
- end
180
- end
181
-
182
- return result
183
- end
184
-
185
- def getRegistResult(command)
186
- m = /RES(B)?([-\d]+)/i.match(command)
187
- unless m
188
- return "1"
189
- end
190
-
191
- value = m[2].to_i
192
- target = value * 5 + 50
193
-
194
- if target < 5
195
- return "(1d100<=#{target}) > 自動失敗"
196
- end
197
-
198
- if target > 95
199
- return "(1d100<=#{target}) > 自動成功"
200
- end
201
-
202
- # 通常判定
203
- total_n = @randomizer.roll_once(100)
204
- result = getCheckResultText(total_n, target)
205
-
206
- return "(1d100<=#{target}) > #{total_n} > #{result}"
207
- end
208
-
209
- def getCombineRoll(command)
210
- m = /CBR(B)?\((\d+),(\d+)\)/i.match(command)
211
- unless m
212
- return "1"
213
- end
214
-
215
- diff_1 = m[2].to_i
216
- diff_2 = m[3].to_i
217
-
218
- total = @randomizer.roll_once(100)
219
-
220
- result_1 = getCheckResultText(total, diff_1)
221
- result_2 = getCheckResultText(total, diff_2)
222
-
223
- successList = ["決定性成功/特殊", "決定性成功", "特殊", "成功"]
224
-
225
- succesCount = 0
226
- succesCount += 1 if successList.include?(result_1)
227
- succesCount += 1 if successList.include?(result_2)
228
- debug("succesCount", succesCount)
51
+ register_prefix_from_super_class()
229
52
 
230
- rank =
231
- if succesCount >= 2
232
- "成功"
233
- elsif succesCount == 1
234
- "部分性成功"
235
- else
236
- "失敗"
237
- end
53
+ def initialize(command)
54
+ super(command)
238
55
 
239
- return "(1d100<=#{diff_1},#{diff_2}) > #{total}[#{result_1},#{result_2}] > #{rank}"
56
+ @locale = :zh_hant
240
57
  end
241
58
  end
242
59
  end