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

Sign up to get free protection for your applications and to get access to all the features.
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