bcdice 3.1.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +154 -75
  3. data/README.md +3 -2
  4. data/i18n/Cthulhu/zh_hans.yml +11 -0
  5. data/i18n/MagicaLogia/zh_hans.yml +564 -0
  6. data/i18n/StellarKnights/ja_jp.yml +498 -0
  7. data/i18n/StellarKnights/ko_kr.yml +498 -0
  8. data/i18n/zh_hans.yml +7 -0
  9. data/lib/bcdice/command/parsed.rb +11 -3
  10. data/lib/bcdice/command/parser.rb +179 -100
  11. data/lib/bcdice/common_command/add_dice.rb +1 -1
  12. data/lib/bcdice/common_command/barabara_dice/node.rb +2 -2
  13. data/lib/bcdice/common_command/barabara_dice/result.rb +6 -0
  14. data/lib/bcdice/common_command/calc.rb +1 -1
  15. data/lib/bcdice/common_command/choice.rb +78 -7
  16. data/lib/bcdice/dice_table.rb +3 -0
  17. data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
  18. data/lib/bcdice/dice_table/d66_left_range_table.rb +29 -0
  19. data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
  20. data/lib/bcdice/game_system.rb +10 -0
  21. data/lib/bcdice/game_system/AceKillerGene.rb +1 -1
  22. data/lib/bcdice/game_system/Ainecadette.rb +68 -0
  23. data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
  24. data/lib/bcdice/game_system/Alsetto.rb +1 -1
  25. data/lib/bcdice/game_system/AlterRaise.rb +2 -2
  26. data/lib/bcdice/game_system/Amadeus.rb +110 -93
  27. data/lib/bcdice/game_system/AngelGear.rb +10 -5
  28. data/lib/bcdice/game_system/AnimaAnimus.rb +16 -9
  29. data/lib/bcdice/game_system/Arianrhod.rb +6 -8
  30. data/lib/bcdice/game_system/Avandner.rb +1 -1
  31. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  32. data/lib/bcdice/game_system/BattleTech.rb +109 -28
  33. data/lib/bcdice/game_system/BeastBindTrinity.rb +28 -12
  34. data/lib/bcdice/game_system/BeginningIdol.rb +5 -5
  35. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +5 -5
  36. data/lib/bcdice/game_system/BladeOfArcana.rb +1 -1
  37. data/lib/bcdice/game_system/BlindMythos.rb +39 -38
  38. data/lib/bcdice/game_system/BloodCrusade.rb +6 -7
  39. data/lib/bcdice/game_system/BloodMoon.rb +9 -8
  40. data/lib/bcdice/game_system/CardRanker.rb +8 -7
  41. data/lib/bcdice/game_system/ChaosFlare.rb +21 -15
  42. data/lib/bcdice/game_system/Chill.rb +10 -10
  43. data/lib/bcdice/game_system/Chill3.rb +9 -9
  44. data/lib/bcdice/game_system/CodeLayerd.rb +39 -39
  45. data/lib/bcdice/game_system/ColossalHunter.rb +34 -47
  46. data/lib/bcdice/game_system/CrashWorld.rb +1 -1
  47. data/lib/bcdice/game_system/Cthulhu.rb +1 -1
  48. data/lib/bcdice/game_system/Cthulhu7th.rb +50 -12
  49. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
  50. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
  51. data/lib/bcdice/game_system/Cthulhu_SimplifiedChinese.rb +60 -0
  52. data/lib/bcdice/game_system/DarkBlaze.rb +0 -11
  53. data/lib/bcdice/game_system/DarkDaysDrive.rb +8 -7
  54. data/lib/bcdice/game_system/DeadlineHeroes.rb +11 -10
  55. data/lib/bcdice/game_system/DemonParasite.rb +5 -13
  56. data/lib/bcdice/game_system/DesperateRun.rb +1 -1
  57. data/lib/bcdice/game_system/DoubleCross.rb +3 -1
  58. data/lib/bcdice/game_system/Dracurouge.rb +3 -2
  59. data/lib/bcdice/game_system/EclipsePhase.rb +14 -14
  60. data/lib/bcdice/game_system/Elric.rb +18 -14
  61. data/lib/bcdice/game_system/Elysion.rb +1 -1
  62. data/lib/bcdice/game_system/EmbryoMachine.rb +9 -8
  63. data/lib/bcdice/game_system/Emoklore.rb +25 -20
  64. data/lib/bcdice/game_system/Fiasco.rb +1 -1
  65. data/lib/bcdice/game_system/FilledWith.rb +4 -0
  66. data/lib/bcdice/game_system/FutariSousa.rb +12 -10
  67. data/lib/bcdice/game_system/GURPS.rb +17 -28
  68. data/lib/bcdice/game_system/Garako.rb +1 -1
  69. data/lib/bcdice/game_system/GardenOrder.rb +12 -7
  70. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
  71. data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
  72. data/lib/bcdice/game_system/Gorilla.rb +2 -8
  73. data/lib/bcdice/game_system/GranCrest.rb +189 -417
  74. data/lib/bcdice/game_system/Gundog.rb +9 -8
  75. data/lib/bcdice/game_system/GundogRevised.rb +10 -9
  76. data/lib/bcdice/game_system/GundogZero.rb +1 -1
  77. data/lib/bcdice/game_system/GurpsFW.rb +16 -16
  78. data/lib/bcdice/game_system/HarnMaster.rb +19 -26
  79. data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
  80. data/lib/bcdice/game_system/Hieizan.rb +12 -21
  81. data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
  82. data/lib/bcdice/game_system/HuntersMoon.rb +5 -10
  83. data/lib/bcdice/game_system/InfiniteFantasia.rb +19 -17
  84. data/lib/bcdice/game_system/Insane.rb +13 -20
  85. data/lib/bcdice/game_system/Irisbane.rb +154 -0
  86. data/lib/bcdice/game_system/IthaWenUa.rb +8 -15
  87. data/lib/bcdice/game_system/JamesBond.rb +10 -10
  88. data/lib/bcdice/game_system/JekyllAndHyde.rb +1 -1
  89. data/lib/bcdice/game_system/Kamigakari.rb +1 -1
  90. data/lib/bcdice/game_system/KanColle.rb +4 -9
  91. data/lib/bcdice/game_system/KemonoNoMori.rb +26 -39
  92. data/lib/bcdice/game_system/KillDeathBusiness.rb +7 -15
  93. data/lib/bcdice/game_system/KurayamiCrying.rb +141 -2
  94. data/lib/bcdice/game_system/LiveraDoll.rb +254 -304
  95. data/lib/bcdice/game_system/LogHorizon.rb +13 -10
  96. data/lib/bcdice/game_system/MagicaLogia_SimplifiedChinese.rb +66 -0
  97. data/lib/bcdice/game_system/MeikyuDays.rb +10 -8
  98. data/lib/bcdice/game_system/MeikyuKingdom.rb +26 -26
  99. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +4 -3
  100. data/lib/bcdice/game_system/MetalHead.rb +12 -22
  101. data/lib/bcdice/game_system/MetalHeadExtream.rb +5 -5
  102. data/lib/bcdice/game_system/MonotoneMuseum.rb +8 -6
  103. data/lib/bcdice/game_system/Nechronica.rb +63 -90
  104. data/lib/bcdice/game_system/NinjaSlayer.rb +6 -7
  105. data/lib/bcdice/game_system/NjslyrBattle.rb +8 -11
  106. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
  107. data/lib/bcdice/game_system/Paradiso.rb +3 -3
  108. data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
  109. data/lib/bcdice/game_system/Peekaboo.rb +4 -9
  110. data/lib/bcdice/game_system/Pendragon.rb +7 -7
  111. data/lib/bcdice/game_system/PersonaO.rb +86 -0
  112. data/lib/bcdice/game_system/PhantasmAdventure.rb +8 -8
  113. data/lib/bcdice/game_system/Postman.rb +1 -1
  114. data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
  115. data/lib/bcdice/game_system/Raisondetre.rb +2 -2
  116. data/lib/bcdice/game_system/Revulture.rb +123 -0
  117. data/lib/bcdice/game_system/RuneQuest.rb +8 -8
  118. data/lib/bcdice/game_system/Ryutama.rb +1 -1
  119. data/lib/bcdice/game_system/SRS.rb +17 -16
  120. data/lib/bcdice/game_system/SamsaraBallad.rb +38 -11
  121. data/lib/bcdice/game_system/Satasupe.rb +32 -32
  122. data/lib/bcdice/game_system/ScreamHighSchool.rb +5 -5
  123. data/lib/bcdice/game_system/SharedFantasia.rb +19 -23
  124. data/lib/bcdice/game_system/ShinobiGami.rb +14 -6
  125. data/lib/bcdice/game_system/Skynauts.rb +103 -142
  126. data/lib/bcdice/game_system/SkynautsBouken.rb +228 -0
  127. data/lib/bcdice/game_system/StarryDolls.rb +318 -0
  128. data/lib/bcdice/game_system/SteamPunkers.rb +25 -7
  129. data/lib/bcdice/game_system/StellarKnights.rb +85 -706
  130. data/lib/bcdice/game_system/StellarKnights_Korean.rb +79 -0
  131. data/lib/bcdice/game_system/SterileLife.rb +2 -3
  132. data/lib/bcdice/game_system/StratoShout.rb +8 -16
  133. data/lib/bcdice/game_system/Strave.rb +1 -1
  134. data/lib/bcdice/game_system/SwordWorld.rb +16 -7
  135. data/lib/bcdice/game_system/SwordWorld2_0.rb +2 -2
  136. data/lib/bcdice/game_system/SwordWorld2_5.rb +2 -2
  137. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  138. data/lib/bcdice/game_system/TokumeiTenkousei.rb +4 -3
  139. data/lib/bcdice/game_system/TokyoGhostResearch.rb +1 -1
  140. data/lib/bcdice/game_system/TorgEternity.rb +2 -2
  141. data/lib/bcdice/game_system/ToshiakiHolyGrailWar.rb +92 -0
  142. data/lib/bcdice/game_system/TrinitySeven.rb +279 -280
  143. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
  144. data/lib/bcdice/game_system/Utakaze.rb +53 -48
  145. data/lib/bcdice/game_system/Villaciel.rb +1 -1
  146. data/lib/bcdice/game_system/WARPS.rb +11 -9
  147. data/lib/bcdice/game_system/WaresBlade.rb +4 -9
  148. data/lib/bcdice/game_system/Warhammer.rb +15 -6
  149. data/lib/bcdice/game_system/Warhammer4.rb +15 -11
  150. data/lib/bcdice/game_system/WitchQuest.rb +1 -1
  151. data/lib/bcdice/game_system/YankeeYogSothoth.rb +4 -9
  152. data/lib/bcdice/game_system/Yggdrasill.rb +1 -1
  153. data/lib/bcdice/game_system/ZettaiReido.rb +20 -25
  154. data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +1 -1
  155. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +4 -4
  156. data/lib/bcdice/game_system/sword_world/rating_parser.rb +1 -1
  157. data/lib/bcdice/game_system/sword_world/transcendent_test.rb +26 -8
  158. data/lib/bcdice/repl.rb +1 -1
  159. data/lib/bcdice/result.rb +26 -0
  160. data/lib/bcdice/version.rb +1 -1
  161. metadata +22 -5
@@ -176,8 +176,7 @@ module BCDice
176
176
  command = bRollCommand(at.num, at.difficulty)
177
177
  roll_result = BCDice::CommonCommand::BarabaraDice.eval(command, self, @randomizer)
178
178
 
179
- values = roll_result.rands.map { |v, _| v }
180
- num_of_max_values = values.count(6)
179
+ num_of_max_values = roll_result.last_dice_list.count(6)
181
180
 
182
181
  parts = [roll_result.text]
183
182
 
@@ -195,7 +194,7 @@ module BCDice
195
194
  command = bRollCommand(el.num, el.difficulty)
196
195
  roll_result = BCDice::CommonCommand::BarabaraDice.eval(command, self, @randomizer)
197
196
 
198
- values = roll_result.rands.map { |v, _| v }
197
+ values = roll_result.last_dice_list
199
198
  num_of_max_values = values.count(6)
200
199
  sum_of_true_values = values.count { |v| v >= el.difficulty }
201
200
 
@@ -253,10 +252,10 @@ module BCDice
253
252
 
254
253
  # ダイスボットで使用するコマンドを配列で列挙する
255
254
  register_prefix(
256
- 'NJ\d+',
257
- 'EV\d+',
258
- 'AT\d+',
259
- 'EL\d+',
255
+ 'NJ',
256
+ 'EV',
257
+ 'AT',
258
+ 'EL',
260
259
  TABLES.keys
261
260
  )
262
261
  end
@@ -21,21 +21,18 @@ module BCDice
21
21
  INFO_MESSAGE_TEXT
22
22
 
23
23
  # ゲーム別成功度判定(2D6)
24
- def check_2D6(total, _dice_total, dice_list, cmp_op, target)
25
- return '' if target == '?'
26
- return '' if cmp_op != :<=
24
+ def result_2d6(total, _dice_total, dice_list, cmp_op, target)
25
+ return Result.nothing if target == "?"
26
+ return nil if cmp_op != :<=
27
27
 
28
- return success_text(total, target) + juuten(dice_list)
29
- end
28
+ result = (total <= target ? Result.success("成功") : Result.failure("失敗"))
29
+ result.text += juuten(dice_list)
30
30
 
31
- def success_text(total, target)
32
- if total <= target
33
- " > 成功"
34
- else
35
- " > 失敗"
36
- end
31
+ return result
37
32
  end
38
33
 
34
+ private
35
+
39
36
  def juuten(dice_list)
40
37
  juuten = dice_list.count(1) + dice_list.count(6)
41
38
 
@@ -127,7 +127,7 @@ module BCDice
127
127
  return "失敗"
128
128
  end
129
129
 
130
- register_prefix('\d*JD', 'RETP?\d+', 'DNGNP?\d+', TABLES.keys)
130
+ register_prefix('\d*JD', 'RETP?', 'DNGNP?', TABLES.keys)
131
131
  end
132
132
  end
133
133
  end
@@ -25,7 +25,7 @@ module BCDice
25
25
   例)DC4:【攻撃力】4でダメージチェック DC5[20]:【攻撃力】5でダメージチェック、うち1つは20mm機銃 DC5[20,30]:【攻撃力】5でダメージチェック、うち1つは20mm機銃、うち1つは30mmガンポッド
26
26
  MESSAGETEXT
27
27
 
28
- register_prefix('(\d+)*D20<=', '(\d+)*CP', 'RMT', 'TOT', 'EXT', 'SUT', 'DC(\d+)')
28
+ register_prefix('\d*D20<=', '\d*CP', 'RMT', 'TOT', 'EXT', 'SUT', 'DC')
29
29
 
30
30
  def eval_game_system_specific_command(command) # ダイスロールコマンド
31
31
  # 通常判定部分をgetJudgeResultコマンドに切り分け
@@ -53,13 +53,13 @@ module BCDice
53
53
  # 通常判定
54
54
  def getJudgeResult(command)
55
55
  case command
56
- when /^(\d+)*D20<=(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
56
+ when /^(\d+)?D20<=(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
57
57
  number = (Regexp.last_match(1) || 1).to_i # ダイス数。省略時は1
58
58
  target = (Regexp.last_match(2) || 14).to_i # 目標値。省略時は14 if 空白 then 14 else 記載の値
59
59
  fumble1 = (Regexp.last_match(4) || 21).to_i # 追加ファンブル値。省略時は21
60
60
  fumble2 = (Regexp.last_match(6) || 21).to_i # 追加ファンブル値。省略時は21
61
61
  critical = (Regexp.last_match(8) || 21).to_i # 追加クリティカル値。省略時は21
62
- when /^(\d+)*CP(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
62
+ when /^(\d+)?CP(\d+)?(\[(\d+)(,(\d+))?\])?(@(\d+))?$/i
63
63
  number = (Regexp.last_match(1) || 1).to_i
64
64
  target = (Regexp.last_match(2) || 14).to_i
65
65
  fumble1 = (Regexp.last_match(4) || 21).to_i
@@ -26,7 +26,7 @@ module BCDice
26
26
  ・D66ダイスあり
27
27
  INFO_MESSAGE_TEXT
28
28
 
29
- register_prefix('(N|A|M|U|C|)?URGE\d+')
29
+ register_prefix('[NAMUC]?URGE')
30
30
 
31
31
  def get_urge(string) # パラサイトブラッドの衝動表
32
32
  unless /(\w*)URGE\s*(\d+)/i =~ string
@@ -45,18 +45,13 @@ module BCDice
45
45
  end
46
46
 
47
47
  # ゲーム別成功度判定(2D6)
48
- def check_2D6(total, dice_total, _dice_list, cmp_op, target)
49
- return '' if target == '?'
50
- return '' unless cmp_op == :>=
48
+ def result_2d6(_total, dice_total, _dice_list, cmp_op, _target)
49
+ return nil unless cmp_op == :>=
51
50
 
52
51
  if dice_total <= 2
53
- return "ファンブル(【眠気】が1d6点上昇)"
52
+ Result.fumble("ファンブル(【眠気】が1d6点上昇)")
54
53
  elsif dice_total >= 12
55
- return "スペシャル(【魔力】あるいは【眠気】が1d6点回復)"
56
- elsif total >= target
57
- return " > 成功"
58
- else
59
- return " > 失敗"
54
+ Result.critical("スペシャル(【魔力】あるいは【眠気】が1d6点回復)")
60
55
  end
61
56
  end
62
57
 
@@ -18,20 +18,20 @@ module BCDice
18
18
  INFO_MESSAGE_TEXT
19
19
 
20
20
  # ゲーム別成功度判定(1d20)
21
- def check_1D20(total, _dice_total, cmp_op, target)
22
- return '' if target == '?'
23
- return '' unless cmp_op == :<=
21
+ def result_1d20(total, _dice_total, cmp_op, target)
22
+ return Result.nothing if target == '?'
23
+ return nil unless cmp_op == :<=
24
24
 
25
25
  if total <= target
26
26
  if (total >= (40 - target)) || (total == target)
27
- "クリティカル"
27
+ Result.critical("クリティカル")
28
28
  else
29
- "成功"
29
+ Result.success("成功")
30
30
  end
31
31
  elsif total == 20
32
- "ファンブル"
32
+ Result.fumble("ファンブル")
33
33
  else
34
- "失敗"
34
+ Result.failure("失敗")
35
35
  end
36
36
  end
37
37
  end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class PersonaO < Base
6
+ # ゲームシステムのの識別子
7
+ ID = 'PersonaO'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'ペルソナTRPG-O'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'へるそなTRPGO'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
+ ・基本判定
18
+  PTx@y x:目標値、y:クリティカル値(省略時は5)
19
+  例)PT60 PT90@10
20
+
21
+ ・ダメージ計算
22
+  nPD+(x+y*2)%(z-a)-b n:ダイス個数、x:スキル固定値、y:ボーナス、z:バフ倍率、a:耐性、b:敵防御力
23
+  nPD+(x+y*2)までがスキルによる素のダメージ、zおよびaは計算式を入れてよい。
24
+  
25
+  例)ソニックパンチ、力B2点、
26
+    タルカジャがかかっており、打撃耐性あり、
27
+    目標の物理防御力は2点
28
+    
29
+    2PD+(20+2*2)%(100+50-50)-2
30
+ INFO_MESSAGE_TEXT
31
+
32
+ register_prefix(
33
+ 'PT',
34
+ '\d+PD'
35
+ )
36
+
37
+ def eval_game_system_specific_command(command)
38
+ roll_attack(command) || roll_damage(command)
39
+ end
40
+
41
+ private
42
+
43
+ def roll_attack(command)
44
+ m = /^PT(-?\d+)?(@(-?\d+))?$/i.match(command)
45
+ unless m
46
+ return nil
47
+ end
48
+
49
+ success_rate = m[1].to_i
50
+ critical_border = m[3]&.to_i || 5
51
+
52
+ dice_value = @randomizer.roll_once(100)
53
+ result =
54
+ if dice_value <= critical_border
55
+ Result.critical("クリティカル")
56
+ elsif dice_value <= success_rate
57
+ Result.success("成功")
58
+ else
59
+ Result.failure("失敗")
60
+ end
61
+
62
+ result.text = "D100<=#{success_rate}@#{critical_border} > #{dice_value} > #{result.text}"
63
+ return result
64
+ end
65
+
66
+ def roll_damage(command)
67
+ m = /^(\d+)PD\+(-?\d+)%(-?\d+)-(\d+)$/i.match(command)
68
+ unless m
69
+ return nil
70
+ end
71
+
72
+ dice = m[1].to_i
73
+ kotei = m[2].to_i
74
+ hosei = m[3].to_i
75
+ bougyo = m[4].to_i
76
+
77
+ dice_list = @randomizer.roll_barabara(dice, 10)
78
+ dice_sum = dice_list.sum
79
+
80
+ dmg = dice_sum + (hosei * kotei / 100.0).to_i - bougyo
81
+
82
+ return "#{dice}D10+#{kotei}*#{hosei}%-#{bougyo} > [#{dice_list.join(',')}]+#{kotei}*#{hosei}%-#{bougyo} > #{dmg} ダメージ!"
83
+ end
84
+ end
85
+ end
86
+ end
@@ -18,9 +18,9 @@ module BCDice
18
18
  INFO_MESSAGE_TEXT
19
19
 
20
20
  # ゲーム別成功度判定(1d20)
21
- def check_1D20(total, _dice_total, cmp_op, diff)
22
- return '' if diff == '?'
23
- return '' unless cmp_op == :<=
21
+ def result_1d20(total, _dice_total, cmp_op, diff)
22
+ return Result.nothing if diff == '?'
23
+ return nil unless cmp_op == :<=
24
24
 
25
25
  # 技能値の修正を計算する
26
26
  skill_mod = 0
@@ -46,7 +46,7 @@ module BCDice
46
46
  else
47
47
  fum_str += "-#{skill_mod}=#{fum_num}"
48
48
  end
49
- return "致命的失敗(#{fum_str})"
49
+ return Result.fumble("致命的失敗(#{fum_str})")
50
50
 
51
51
  elsif (total <= critical) || (total <= 1)
52
52
  crit_num = dice_now + skill_mod
@@ -54,14 +54,14 @@ module BCDice
54
54
  crit_num = 1 if crit_num < 1
55
55
 
56
56
  if skill_mod < 0
57
- return "成功"
57
+ return Result.success("成功")
58
58
  end
59
59
 
60
- return "決定的成功(#{dice_now}+#{skill_mod}=#{crit_num})"
60
+ return Result.critical("決定的成功(#{dice_now}+#{skill_mod}=#{crit_num})")
61
61
  elsif total <= diff
62
- return "成功"
62
+ return Result.success("成功")
63
63
  else
64
- return "失敗"
64
+ return Result.failure("失敗")
65
65
  end
66
66
  end
67
67
  end
@@ -38,7 +38,7 @@ module BCDice
38
38
  MESSAGETEXT
39
39
 
40
40
  register_prefix(
41
- 'WEA\d*',
41
+ 'WEA',
42
42
  '(\d+)?PO',
43
43
  'FRE'
44
44
  )
@@ -47,7 +47,7 @@ module BCDice
47
47
   ・プッシュ時のキャスティング・ロールの失敗(Failed Casting Effects)表 FCE
48
48
  INFO_MESSAGE_TEXT
49
49
 
50
- register_prefix('CC\(\d+\)', 'CC', 'CBR\(\d+,\d+\)', 'FAR', 'BMR', 'BMS', 'FCE', 'PH', 'MA', 'IT')
50
+ register_prefix('CC', 'CBR', 'FAR', 'BMR', 'BMS', 'FCE', 'PH', 'MA', 'IT')
51
51
 
52
52
  def eval_game_system_specific_command(command)
53
53
  case command
@@ -39,8 +39,8 @@ module BCDice
39
39
  end
40
40
 
41
41
  register_prefix(
42
- '(-)?(\d+)?RD(\d+)?(@(\d+))?',
43
- '(-)?(\d+)?DD([1-9])?([\+\-]\d+)?'
42
+ '(-)?(\d+)?RD',
43
+ '(-)?(\d+)?DD'
44
44
  )
45
45
 
46
46
  def eval_game_system_specific_command(command)
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Revulture < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'Revulture'
8
+
9
+ # ゲームシステム名
10
+ NAME = '光砕のリヴァルチャー'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'こうさいのりうあるちやあ'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~HELP
17
+ ■アタック判定( xAT, xATK, xATTACK )
18
+ x: ダイス数(加算 + と除算 / を使用可能)
19
+ 例) 3AT, 4ATK, 5+6ATTACK, 15/2AT
20
+
21
+ □アタック判定 目標値つき( xAT<=y, xATK<=y, xATTACK<=y )
22
+ x: ダイス数(加算 + と除算 / を使用可能)
23
+ y: 目標値( 1 以上 6 以下。加算 + を使用可能)
24
+ 例) 3AT<=4, 3AT<=2+1
25
+
26
+ □アタック判定 目標値&追加ダメージつき( xAT<=y[>=a:+b], xATK<=y[>=a:+b], xATTACK<=y[z] )
27
+ x: ダイス数(加算 + と除算 / を使用可能)
28
+ y: 目標値( 1 以上 6 以下。加算 + を使用可能)
29
+ z: 追加ダメージの規則(詳細は後述)(※複数同時に指定可能)
30
+
31
+ ▽追加ダメージの規則 [a:+b]
32
+ a: ヒット数が a なら
33
+  =a (ヒット数が a に等しい)
34
+  >=a (ヒット数が a 以上)
35
+ b: ダメージを b 点追加
36
+
37
+ 例) 3AT<=4[>=2:+3] #ルールブックp056「グレングラントAR」
38
+ 例) 2AT<=4[=1:+5][>=2:+8] #ルールブックp067「ファーボル・ドラゴンブレス」
39
+ HELP
40
+
41
+ ATTACK_ROLL_REG = %r{^(\d+([+/]\d+)*)?AT(TACK|K)?(<=([1-6](\+\d)*))?((\[>?=\d+:\+\d+\])+)?}i.freeze
42
+ register_prefix('\d+([+\/]\d+)*AT')
43
+
44
+ def eval_game_system_specific_command(command)
45
+ if (m = ATTACK_ROLL_REG.match(command))
46
+ roll_attack(m[1], m[5], m[7])
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def roll_attack(dice_count_expression, border_expression, additional_damage_rules)
53
+ dice_count = Arithmetic.eval(dice_count_expression, RoundType::FLOOR)
54
+ border = Arithmetic.eval(border_expression, RoundType::FLOOR).clamp(1, 6) if border_expression
55
+
56
+ command = make_command_text(dice_count, border, additional_damage_rules)
57
+
58
+ if dice_count <= 0
59
+ return "#{command} > ダイス数が 0 です"
60
+ elsif border.nil? && additional_damage_rules
61
+ return "#{command} > 目標値が指定されていないため、追加ダメージを算出できません"
62
+ end
63
+
64
+ dices = @randomizer.roll_barabara(dice_count, 6).sort
65
+
66
+ critical_hit_count = dices.count(1)
67
+ hit_count = dices.count { |dice| dice <= border } + critical_hit_count if border
68
+ damage = calc_damage(hit_count, additional_damage_rules)
69
+
70
+ message_elements = []
71
+ message_elements << command
72
+ message_elements << dices.join(',')
73
+ message_elements << "クリティカル #{critical_hit_count}" if critical_hit_count > 0
74
+ message_elements << "ヒット数 #{hit_count}" if hit_count
75
+ message_elements << "ダメージ #{damage}" if damage
76
+
77
+ Result.new(message_elements.join(' > ')).tap do |r|
78
+ r.condition = hit_count > 0 if hit_count
79
+ r.critical = critical_hit_count > 0
80
+ end
81
+ end
82
+
83
+ def make_command_text(dice_count, border, additional_damage_rules)
84
+ command = "#{dice_count}attack"
85
+ command += "<=#{border}" if border
86
+ command += additional_damage_rules if additional_damage_rules
87
+
88
+ "(#{command})"
89
+ end
90
+
91
+ def calc_damage(hit_count, additional_damage_rules)
92
+ return nil unless additional_damage_rules
93
+
94
+ damage = hit_count
95
+ parse_additional_damage_rules(additional_damage_rules).each do |rule|
96
+ if rule[:condition].call(hit_count)
97
+ damage += rule[:additinal_damage]
98
+ end
99
+ end
100
+
101
+ damage
102
+ end
103
+
104
+ def parse_additional_damage_rules(source)
105
+ source.scan(/\[(>?=)(\d+):\+(\d+)\]/).map do |matched|
106
+ {
107
+ condition: make_additional_damage_condition(matched[0], matched[1].to_i),
108
+ additinal_damage: matched[2].to_i,
109
+ }
110
+ end
111
+ end
112
+
113
+ def make_additional_damage_condition(comparer, comparing_target)
114
+ case comparer
115
+ when '='
116
+ lambda { |hit_count| hit_count == comparing_target }
117
+ when '>='
118
+ lambda { |hit_count| hit_count >= comparing_target }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end