bcdice 3.13.0 → 3.15.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/i18n/Arianrhod/ko_kr.yml +3 -0
  4. data/i18n/Cthulhu/en_us.yml +11 -0
  5. data/i18n/Cthulhu/zh_hant.yml +1 -1
  6. data/i18n/CyberpunkRed/ja_jp.yml +389 -0
  7. data/i18n/CyberpunkRed/ko_kr.yml +389 -0
  8. data/i18n/DoubleCross/ja_jp.yml +53 -0
  9. data/i18n/DoubleCross/ko_kr.yml +52 -0
  10. data/i18n/FinalFantasyXIV/en_us.yml +4 -0
  11. data/i18n/FinalFantasyXIV/ja_jp.yml +4 -0
  12. data/i18n/FutariSousa/ja_jp.yml +284 -127
  13. data/i18n/KillDeathBusiness/ja_jp.yml +198 -0
  14. data/i18n/KizunaBullet/ja_jp.yml +653 -0
  15. data/i18n/MagicaLogia/ko_kr.yml +2 -2
  16. data/i18n/MonotoneMuseum/ja_jp.yml +246 -14
  17. data/i18n/MonotoneMuseum/ko_kr.yml +227 -0
  18. data/i18n/SkynautsBouken/ja_jp.yml +114 -0
  19. data/i18n/SkynautsBouken/ko_kr.yml +114 -0
  20. data/i18n/StratoShout/ko_kr.yml +102 -102
  21. data/i18n/TensaiGunshiNiNaro/ja_jp.yml +126 -0
  22. data/i18n/UnsungDuet/ja_jp.yml +62 -0
  23. data/i18n/UnsungDuet/ko_kr.yml +62 -0
  24. data/i18n/en_us.yml +5 -0
  25. data/i18n/zh_hant.yml +5 -0
  26. data/lib/bcdice/dice_table/range_table.rb +24 -0
  27. data/lib/bcdice/game_system/Agnostos.rb +248 -0
  28. data/lib/bcdice/game_system/Aionia.rb +131 -0
  29. data/lib/bcdice/game_system/AniMalus.rb +99 -59
  30. data/lib/bcdice/game_system/Arianrhod_Korean.rb +32 -0
  31. data/lib/bcdice/game_system/ArknightsFan.rb +245 -87
  32. data/lib/bcdice/game_system/BlackJacket.rb +244 -0
  33. data/lib/bcdice/game_system/BlackJacket_Korean.rb +244 -0
  34. data/lib/bcdice/game_system/CharonSanctions.rb +112 -0
  35. data/lib/bcdice/game_system/ConvictorDrive.rb +5 -4
  36. data/lib/bcdice/game_system/Cthulhu7th.rb +1 -1
  37. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/full_auto.rb +293 -0
  38. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/rollable.rb +43 -0
  39. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +470 -306
  40. data/lib/bcdice/game_system/Cthulhu_English.rb +59 -0
  41. data/lib/bcdice/game_system/CyberpunkRed.rb +15 -6
  42. data/lib/bcdice/game_system/CyberpunkRed_Korean.rb +66 -0
  43. data/lib/bcdice/game_system/DivineCharger.rb +841 -0
  44. data/lib/bcdice/game_system/DoubleCross.rb +18 -1
  45. data/lib/bcdice/game_system/DoubleCross_Korean.rb +5 -1
  46. data/lib/bcdice/game_system/FinalFantasyXIV.rb +115 -0
  47. data/lib/bcdice/game_system/FinalFantasyXIV_English.rb +39 -0
  48. data/lib/bcdice/game_system/FullFace.rb +63 -12
  49. data/lib/bcdice/game_system/FutariSousa.rb +105 -13
  50. data/lib/bcdice/game_system/Garactier.rb +479 -0
  51. data/lib/bcdice/game_system/GardenOrder.rb +390 -9
  52. data/lib/bcdice/game_system/GundogRevised.rb +8 -8
  53. data/lib/bcdice/game_system/Insane_Korean.rb +1 -1
  54. data/lib/bcdice/game_system/InvisibleLiar.rb +79 -0
  55. data/lib/bcdice/game_system/KillDeathBusiness.rb +155 -3
  56. data/lib/bcdice/game_system/KimitoYell.rb +568 -0
  57. data/lib/bcdice/game_system/KizunaBullet.rb +240 -0
  58. data/lib/bcdice/game_system/KyokoShinshoku.rb +51 -8
  59. data/lib/bcdice/game_system/Magius.rb +125 -0
  60. data/lib/bcdice/game_system/Magius_3rdNewTokyoCity.rb +62 -0
  61. data/lib/bcdice/game_system/MonotoneMuseum.rb +14 -1
  62. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
  63. data/lib/bcdice/game_system/NRR.rb +2 -2
  64. data/lib/bcdice/game_system/NSSQ.rb +17 -9
  65. data/lib/bcdice/game_system/NervWhitePaper.rb +129 -0
  66. data/lib/bcdice/game_system/RogueLikeHalf.rb +198 -0
  67. data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +16 -13
  68. data/lib/bcdice/game_system/ShinobiGami.rb +73 -43
  69. data/lib/bcdice/game_system/ShuumatsuBargainWars.rb +203 -0
  70. data/lib/bcdice/game_system/SkynautsBouken.rb +49 -134
  71. data/lib/bcdice/game_system/SkynautsBouken_Korean.rb +57 -0
  72. data/lib/bcdice/game_system/StratoShout_Korean.rb +1 -1
  73. data/lib/bcdice/game_system/SwordWorld.rb +5 -1
  74. data/lib/bcdice/game_system/SwordWorld2_5.rb +3 -2
  75. data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +262 -0
  76. data/lib/bcdice/game_system/TheIndieHack.rb +82 -0
  77. data/lib/bcdice/game_system/TheOneRing2nd.rb +406 -0
  78. data/lib/bcdice/game_system/TheUnofficialHollowKnightRPG.rb +185 -0
  79. data/lib/bcdice/game_system/TorgEternity.rb +35 -6
  80. data/lib/bcdice/game_system/TrailOfCthulhu.rb +139 -0
  81. data/lib/bcdice/game_system/UnsungDuet.rb +17 -75
  82. data/lib/bcdice/game_system/UnsungDuet_Korean.rb +41 -0
  83. data/lib/bcdice/game_system/Utakaze.rb +55 -2
  84. data/lib/bcdice/game_system/Warhammer4.rb +124 -3
  85. data/lib/bcdice/game_system/WoW.rb +161 -0
  86. data/lib/bcdice/game_system/YankeeMustDie.rb +192 -0
  87. data/lib/bcdice/game_system/YearZeroEngine.rb +225 -28
  88. data/lib/bcdice/game_system/Yotabana.rb +62 -0
  89. data/lib/bcdice/game_system/YuMyoKishi.rb +141 -0
  90. data/lib/bcdice/game_system/cyberpunk_red/tables.rb +111 -473
  91. data/lib/bcdice/game_system/kizuna_bullet/tables.rb +171 -0
  92. data/lib/bcdice/game_system/sword_world/rating_lexer.rb +1 -0
  93. data/lib/bcdice/game_system/sword_world/rating_options.rb +4 -1
  94. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +5 -0
  95. data/lib/bcdice/game_system/sword_world/rating_parser.rb +129 -115
  96. data/lib/bcdice/game_system.rb +31 -0
  97. data/lib/bcdice/version.rb +1 -1
  98. metadata +50 -6
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Agnostos < Base
6
+ # ゲームシステムの識別子
7
+ ID = "Agnostos"
8
+
9
+ # ゲームシステム名
10
+ NAME = "アグノストス"
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = "あくのすとす"
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~MESSAGETEXT
17
+ ■ 行為判定
18
+ CDx>=t
19
+ x: コンディションレベル(A~E もしくは 5~1)
20
+ t: 目標値
21
+ の成否とコンディションの変動量を判定します。
22
+
23
+ ■ 心拍のコンディションチェック
24
+ HCDx
25
+ x: コンディションレベル(C+, B+, A, B-, C-, もしくは 5~1)
26
+ 酸素の消費量、コンディションの変動量、気絶したかを判定します。
27
+
28
+ ■ 必殺技
29
+ xSPy
30
+ x: メインコンディション(A~E もしくは 5~1)
31
+ y: サブコンディション(A~E もしくは 5~1)
32
+ 必殺技のダメージ量を判定します。
33
+ MESSAGETEXT
34
+
35
+ register_prefix('CD', 'HCD', '[A-E1-5]SP[A-E1-5]')
36
+
37
+ def eval_game_system_specific_command(command)
38
+ condition_roll(command) || heart_condition_roll(command) || special_roll(command)
39
+ end
40
+
41
+ private
42
+
43
+ # コンディションチェック
44
+ def condition_roll(command)
45
+ parser = Command::Parser.new(/CD[A-E1-5]/, round_type: @round_type).disable_modifier.restrict_cmp_op_to(:>=)
46
+ parsed = parser.parse(command)
47
+ unless parsed
48
+ return nil
49
+ end
50
+
51
+ condition_level = to_condition_level(parsed.command[-1])
52
+ sides = to_sides(condition_level)
53
+ value = @randomizer.roll_once(sides)
54
+
55
+ Result.new.tap do |r|
56
+ r.critical = critical?(sides, value)
57
+ r.fumble = fumble?(sides, value)
58
+ r.condition = value >= parsed.target_number
59
+
60
+ r.text = [
61
+ "(CD#{condition_level}>=#{parsed.target_number})",
62
+ "(1D#{sides}>=#{parsed.target_number})",
63
+ value.to_s(),
64
+ r.success? ? "成功" : "失敗",
65
+ condition_change(sides, value),
66
+ ].join(" > ")
67
+ end
68
+ end
69
+
70
+ def to_condition_level(char)
71
+ case char
72
+ when "5"
73
+ "A"
74
+ when "4"
75
+ "B"
76
+ when "3"
77
+ "C"
78
+ when "2"
79
+ "D"
80
+ when "1"
81
+ "E"
82
+ else
83
+ char
84
+ end
85
+ end
86
+
87
+ def to_sides(condition)
88
+ case condition
89
+ when "A"
90
+ 12
91
+ when "B"
92
+ 10
93
+ when "C"
94
+ 8
95
+ when "D"
96
+ 6
97
+ else # "E"
98
+ 4
99
+ end
100
+ end
101
+
102
+ def condition_change(sides, value)
103
+ if critical?(sides, value)
104
+ "コンディション:2段階上昇(クリティカル)"
105
+ elsif fumble?(sides, value)
106
+ "コンディション:2段階下降(ファンブル)"
107
+ elsif sides != 12 && sides - value <= 1
108
+ "コンディション:1段階上昇"
109
+ elsif sides == 12 && value <= 6
110
+ "コンディション:1段階下降"
111
+ elsif sides == 10 && value <= 3
112
+ "コンディション:1段階下降"
113
+ elsif sides == 8 && value <= 2
114
+ "コンディション:1段階下降"
115
+ else
116
+ "コンディション:変動なし"
117
+ end
118
+ end
119
+
120
+ def critical?(sides, value)
121
+ sides != 12 && sides == value
122
+ end
123
+
124
+ def fumble?(sides, value)
125
+ sides != 4 && value == 1
126
+ end
127
+
128
+ # 心拍のコンディションチェック
129
+ def heart_condition_roll(command)
130
+ m = /^HCD([A1-5]|[BC][+-])$/.match(command)
131
+ unless m
132
+ return nil
133
+ end
134
+
135
+ suffix = m[1]
136
+ condition_level = to_heart_condition_level(suffix)
137
+ sides = to_heart_sides(condition_level)
138
+ value = @randomizer.roll_once(sides)
139
+
140
+ Result.new.tap do |r|
141
+ r.critical = critical?(sides, value)
142
+ r.fumble = fumble?(sides, value)
143
+
144
+ r.text = [
145
+ "(HCD#{condition_level})",
146
+ "(1D#{sides})",
147
+ value.to_s(),
148
+ heart_condition_change(sides, value),
149
+ ].join(" > ")
150
+ end
151
+ end
152
+
153
+ def to_heart_condition_level(char)
154
+ case char
155
+ when "5"
156
+ "C+"
157
+ when "4"
158
+ "B+"
159
+ when "3"
160
+ "A"
161
+ when "2"
162
+ "B-"
163
+ when "1"
164
+ "C-"
165
+ else
166
+ char
167
+ end
168
+ end
169
+
170
+ def to_heart_sides(condition)
171
+ case condition
172
+ when "C+"
173
+ 12
174
+ when "B+"
175
+ 10
176
+ when "A"
177
+ 8
178
+ when "B-"
179
+ 6
180
+ else # "C-"
181
+ 4
182
+ end
183
+ end
184
+
185
+ def fainted?(sides, value)
186
+ case sides
187
+ when 12
188
+ value >= 7
189
+ when 10
190
+ value >= 10
191
+ when 8
192
+ false
193
+ when 6
194
+ value <= 1
195
+ else # 4
196
+ value <= 2
197
+ end
198
+ end
199
+
200
+ def heart_condition_change(sides, value)
201
+ if fainted?(sides, value)
202
+ "気絶"
203
+ else
204
+ condition_change(sides, value)
205
+ end
206
+ end
207
+
208
+ # 必殺技
209
+ def special_roll(command)
210
+ m = /^([A-E1-5])SP([A-E1-5])$/.match(command)
211
+ unless m
212
+ return nil
213
+ end
214
+
215
+ times_conditon_level = to_condition_level(m[1])
216
+ sides_conditon_level = to_condition_level(m[2])
217
+
218
+ times = to_times(times_conditon_level)
219
+ sides = to_sides(sides_conditon_level)
220
+
221
+ dice_list = @randomizer.roll_barabara(times, sides)
222
+ value = dice_list.sum()
223
+
224
+ return [
225
+ "(#{times_conditon_level}SP#{sides_conditon_level})",
226
+ "(#{times}D#{sides})",
227
+ "#{value}[#{dice_list.join(',')}]",
228
+ value.to_s(),
229
+ ].join(" > ")
230
+ end
231
+
232
+ def to_times(condition)
233
+ case condition
234
+ when "A"
235
+ 5
236
+ when "B"
237
+ 4
238
+ when "C"
239
+ 3
240
+ when "D"
241
+ 2
242
+ else # "E"
243
+ 1
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Aionia < Base
6
+ # ゲームシステムの識別子
7
+ ID = "Aionia"
8
+
9
+ # ゲームシステム名
10
+ NAME = "慈悲なきアイオニア"
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = "しひなきあいおにあ"
14
+
15
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
16
+ - 技能判定(クリティカル・ファンブルなし)
17
+ AB{n}>={dif} n=10面ダイスの数、dif=難易度
18
+ - 技能判定(クリティカル・ファンブルあり)
19
+ ABT{n}>={dif} n=10面ダイスの数、dif=難易度
20
+
21
+ 例:AB2>=5 (一般技能を活用して難易度5の技能判定。 クリファンなし。)
22
+ 例:ABT3>=15 (専門技能を活用して難易度15の技能判定。クリファンあり。)
23
+ 例:AB1+2>=8 (一般技能を活用せず難易度8の技能判定。 ボーナスとして+2点の補正あり。 クリファンなし。)
24
+ 例:ABT3-3>=10 (専門技能を活用して難易度10の技能判定。ペナルティとして-3点の補正あり。クリファンあり。)
25
+ 例:ABT2>=4/8/12 (一般技能を活用して難易度4/8/12の段階的な技能判定。クリファンあり。)
26
+ INFO_MESSAGE_TEXT
27
+
28
+ register_prefix('ABT?\d+([\+\-]\d+)?>=\d+(\/\d+)*')
29
+
30
+ def eval_game_system_specific_command(command)
31
+ return roll_skills(command)
32
+ end
33
+
34
+ def roll_skills(command)
35
+ m = %r{AB(T?)(\d+)([+-]\d+)?>=((\d+)((/\d+)*))}.match(command)
36
+ return nil unless m
37
+
38
+ # 値の取得
39
+ use_cf = m[1] != ''
40
+ times = m[2].to_i
41
+ bonus = m[3].to_i
42
+ targets = m[4].split('/').map(&:to_i)
43
+ target = targets[0]
44
+ min_target = targets.min
45
+ max_target = targets.max
46
+
47
+ # ダイスロール
48
+ dice_list = @randomizer.roll_barabara(times, 10)
49
+ dice_total = dice_list.sum
50
+ total = dice_total + bonus
51
+
52
+ # Result用変数宣言
53
+ is_success = false
54
+ has_critical = false
55
+ has_fumble = false
56
+
57
+ # 結果判定
58
+ # 難易度が一つの場合
59
+ if targets.count == 1
60
+ if total >= target
61
+ is_success = true
62
+ if total >= target + 20 && use_cf
63
+ result = 'クリティカル'
64
+ has_critical = true
65
+ elsif target <= times
66
+ result = '自動成功'
67
+ else
68
+ result = '成功'
69
+ end
70
+ else
71
+ is_success = false
72
+ if dice_list.count(1) == times && use_cf
73
+ result = 'ファンブル'
74
+ has_fumble = true
75
+ elsif target > 10 * times
76
+ result = '自動失敗'
77
+ else
78
+ result = '失敗'
79
+ end
80
+ end
81
+ # 段階的な難易度判定の場合
82
+ else
83
+ if total >= min_target
84
+ is_success = true
85
+ if total >= max_target + 20 && use_cf
86
+ result = 'クリティカル'
87
+ has_critical = true
88
+ elsif max_target <= times
89
+ result = '自動成功'
90
+ elsif total >= max_target
91
+ result = '全成功'
92
+ else
93
+ times_suc = targets.count { |x| x <= total }
94
+ result = "#{times_suc}段階成功"
95
+ end
96
+ else
97
+ is_success = false
98
+ if dice_list.count(1) == times && use_cf
99
+ result = 'ファンブル'
100
+ has_fumble = true
101
+ elsif min_target > 10 * times
102
+ result = '自動失敗'
103
+ else
104
+ result = '失敗'
105
+ end
106
+ end
107
+ end
108
+
109
+ # ボーナスがある場合の処理
110
+ bonus_text = ''
111
+ bonus_result = ''
112
+ if bonus != 0
113
+ if bonus > 0
114
+ bonus_text = "+"
115
+ end
116
+ bonus_text += bonus.to_s
117
+ bonus_result = "#{total} > "
118
+ end
119
+
120
+ # Resultクラスに結果を入れる
121
+ Result.new.tap do |r|
122
+ r.text = "(#{command}) > #{dice_total}[#{dice_list.join(',')}]#{bonus_text} > #{bonus_result}#{result}"
123
+ r.critical = has_critical
124
+ r.fumble = has_fumble
125
+ r.success = is_success
126
+ r.failure = !is_success
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -14,23 +14,23 @@ module BCDice
14
14
 
15
15
  # ダイスボットの使い方
16
16
  HELP_MESSAGE = <<~INFO_MESSAGETEXT
17
- ■ステータスのダイス判定 nAM<=t,x n:能力値 t:成功値 x:必要成功数
18
- 例)3AM<=2,1: ダイスを3個振って、成功値2,必要成功数1で判定。その結果(成功数,成功・失敗)を表示
17
+ ■ステータスのダイス判定 n[+-b]AM<=t,x n:能力値 b:修正値(省略可能) t:成功値 x:必要成功数
18
+ 例)3AM<=2,1: ダイスを3個振って、成功値2,必要成功数1で判定。その結果(成功数,成功・失敗,クリティカル,ファンブル)を表示
19
19
 
20
- ■探索技能のダイス判定 AI<=t,x t:探索技能レベル x:必要成功数
21
- 例)AI<=3,1: ダイスを3個振って、探索技能レベル3,必要成功数1で判定。その結果(成功数,成功・失敗)を表示
20
+ ■探索技能のダイス判定 [+-b]AI<=t,x t:探索技能レベル b:修正値(省略可能) x:必要成功数
21
+ 例)AI<=3,1: ダイスを3個振って、探索技能レベル3,必要成功数1で判定。その結果(成功数,成功・失敗,クリティカル,ファンブル)を表示
22
22
 
23
- ■攻撃判定 AA<=t t:戦闘技能レベル
23
+ ■攻撃判定 [+-b]AA<=t t:戦闘技能レベル b:修正値(省略可能)
24
24
  例)AA<=3: ダイスを3個振って、戦闘技能レベル3で判定。その結果(成功・失敗,ダメージ,クリティカル,ファンブル)を表示
25
25
 
26
- ■防御判定 AG=t t:攻撃技能レベル
27
- 例)AG=2: ダイスを3個振って、攻撃技能レベル2で判定。その結果(成功・失敗,ダメージ,クリティカル,ファンブル)を表示
26
+ ■防御判定 [+-b]AG=t t:攻撃技能レベル b:修正値(省略可能)
27
+ 例)AG=2: ダイスを3個振って、攻撃技能レベル2で判定。その結果(成功・失敗,ダメージ軽減,クリティカル,ファンブル)を表示
28
28
 
29
- ■回避判定 AD=t t:攻撃技能レベル
29
+ ■回避判定 [+-b]AD=t t:攻撃技能レベル b:修正値(省略可能)
30
30
  例)AD=3: ダイスを1個振って、攻撃技能レベル3で判定。その結果(成功・失敗)を表示
31
31
  INFO_MESSAGETEXT
32
32
 
33
- register_prefix('\d*A[MIAGD]')
33
+ register_prefix('[-+\d]*A[MIAGD]')
34
34
 
35
35
  def initialize(command)
36
36
  super(command)
@@ -48,27 +48,53 @@ module BCDice
48
48
 
49
49
  private
50
50
 
51
+ def with_symbol(number)
52
+ if number == 0
53
+ return ""
54
+ elsif number > 0
55
+ return "+#{number}"
56
+ else
57
+ return number.to_s
58
+ end
59
+ end
60
+
51
61
  # ステータスの判定
52
62
  # @param [String] command
53
63
  # @return [Result]
54
64
  def resolute_action(command)
55
- m = /^(\d+)AM<=(\d+),(\d)$/.match(command)
65
+ m = /^(\d+)([-+]\d+)?AM<=(\d+),(\d)$/.match(command)
56
66
  return nil unless m
57
67
 
58
68
  num_dice = m[1].to_i
59
- num_target = m[2].to_i
60
- num_success = m[3].to_i
69
+ num_bonus = m[2].to_i
70
+ num_target = m[3].to_i
71
+ num_success = m[4].to_i
61
72
 
62
- dice = @randomizer.roll_barabara(num_dice, 6).sort
73
+ dice = @randomizer.roll_barabara(num_dice + num_bonus, 6).sort
63
74
  dice_text = dice.join(",")
64
75
  success_num = dice.count { |val| val <= num_target }
65
- output = "(#{num_dice}AM<=#{num_target},#{num_success}) #{dice_text} 成功数#{success_num}"
66
- if success_num >= num_success
67
- output += " > 成功"
68
- return Result.success(output)
69
- else
70
- output += " > 失敗"
71
- return Result.failure(output)
76
+ is_critical = dice.include?(1) && dice.include?(2) && dice.include?(3)
77
+ is_fumble = dice.include?(4) && dice.include?(5) && dice.include?(6)
78
+
79
+ return Result.new.tap do |result|
80
+ result.critical = is_critical
81
+ result.fumble = is_fumble
82
+ result.condition = (success_num >= num_success)
83
+
84
+ sequence = [
85
+ "(#{num_dice}#{with_symbol(num_bonus)}AM<=#{num_target},#{num_success})",
86
+ dice_text,
87
+ "成功数#{success_num}",
88
+ if result.success?
89
+ "成功"
90
+ else
91
+ "失敗"
92
+ end
93
+ ].compact
94
+ sequence.push("クリティカル") if result.critical?
95
+ sequence.push("ファンブル") if result.fumble?
96
+
97
+ result.text = sequence.join(" > ")
72
98
  end
73
99
  end
74
100
 
@@ -76,22 +102,38 @@ module BCDice
76
102
  # @param [String] command
77
103
  # @return [Result]
78
104
  def resolute_investigation(command)
79
- m = /^AI<=(\d+),(\d)$/.match(command)
105
+ m = /^([-+]\d+)?AI<=(\d+),(\d)$/.match(command)
80
106
  return nil unless m
81
107
 
82
- num_target = m[1].to_i
83
- num_success = m[2].to_i
108
+ num_bonus = m[1].to_i
109
+ num_target = m[2].to_i
110
+ num_success = m[3].to_i
84
111
 
85
- dice = @randomizer.roll_barabara(3, 6).sort
112
+ dice = @randomizer.roll_barabara(3 + num_bonus, 6).sort
86
113
  dice_text = dice.join(",")
87
114
  success_num = dice.count { |val| val <= num_target }
88
- output = "(AI<=#{num_target},#{num_success}) #{dice_text} 成功数#{success_num}"
89
- if success_num >= num_success
90
- output += " > 成功"
91
- return Result.success(output)
92
- else
93
- output += " > 失敗"
94
- return Result.failure(output)
115
+ is_critical = dice.include?(1) && dice.include?(2) && dice.include?(3)
116
+ is_fumble = dice.include?(4) && dice.include?(5) && dice.include?(6)
117
+
118
+ return Result.new.tap do |result|
119
+ result.critical = is_critical
120
+ result.fumble = is_fumble
121
+ result.condition = (success_num >= num_success)
122
+
123
+ sequence = [
124
+ "(#{with_symbol(num_bonus)}AI<=#{num_target},#{num_success})",
125
+ dice_text,
126
+ "成功数#{success_num}",
127
+ if result.success?
128
+ "成功"
129
+ else
130
+ "失敗"
131
+ end
132
+ ].compact
133
+ sequence.push("クリティカル") if result.critical?
134
+ sequence.push("ファンブル") if result.fumble?
135
+
136
+ result.text = sequence.join(" > ")
95
137
  end
96
138
  end
97
139
 
@@ -99,25 +141,25 @@ module BCDice
99
141
  # @param [String] command
100
142
  # @return [Result]
101
143
  def resolute_attacking(command)
102
- m = /^AA<=(\d+)$/.match(command)
144
+ m = /^([-+]\d+)?AA<=(\d+)$/.match(command)
103
145
  return nil unless m
104
146
 
105
- num_target = m[1].to_i
147
+ num_bonus = m[1].to_i
148
+ num_target = m[2].to_i
106
149
 
107
- dice = @randomizer.roll_barabara(3, 6).sort
150
+ dice = @randomizer.roll_barabara(3 + num_bonus, 6).sort
108
151
  dice_text = dice.join(",")
109
152
  success_num = dice.count { |val| val <= num_target }
110
- is_critical = dice[0] == 1 && dice[1] == 2 && dice[2] == 3
111
- is_fumble = dice[0] == 4 && dice[1] == 5 && dice[2] == 6
153
+ is_critical = dice.include?(1) && dice.include?(2) && dice.include?(3)
154
+ is_fumble = dice.include?(4) && dice.include?(5) && dice.include?(6)
155
+
112
156
  damage1 = dice.max
113
157
  damage2 = dice.max
114
- if dice[0] == dice[1] && dice[1] == dice[2] && dice[2] <= num_target
115
- damage2 += 6
116
- damage1 = damage2
117
- elsif dice[0] == dice[1] && dice[1] <= num_target
118
- damage2 += 3
119
- elsif dice[1] == dice[2] && dice[2] <= num_target
120
- damage2 += 3
158
+ (1..num_target).each do |idx|
159
+ if dice.count(idx) > 1
160
+ now_damage = damage1 + 3 * (dice.count(idx) - 1)
161
+ damage2 = now_damage if damage2 < now_damage
162
+ end
121
163
  end
122
164
 
123
165
  return Result.new.tap do |result|
@@ -126,7 +168,7 @@ module BCDice
126
168
  result.condition = (success_num > 0)
127
169
 
128
170
  sequence = [
129
- "(AA<=#{num_target})",
171
+ "(#{with_symbol(num_bonus)}AA<=#{num_target})",
130
172
  dice_text,
131
173
  "成功数#{success_num}",
132
174
  if result.success?
@@ -136,11 +178,7 @@ module BCDice
136
178
  end
137
179
  ].compact
138
180
  if result.success?
139
- if damage1 == damage2
140
- sequence.push("ダメージ(#{damage1})")
141
- else
142
- sequence.push("ダメージ(#{damage1}か#{damage2})")
143
- end
181
+ sequence.push("最大ダメージ(#{damage2})")
144
182
  end
145
183
  sequence.push("クリティカル") if result.critical?
146
184
  sequence.push("ファンブル") if result.fumble?
@@ -153,16 +191,17 @@ module BCDice
153
191
  # @param [String] command
154
192
  # @return [Result]
155
193
  def resolute_guarding(command)
156
- m = /^AG=(\d+)$/.match(command)
194
+ m = /^([-+]\d+)?AG=(\d+)$/.match(command)
157
195
  return nil unless m
158
196
 
159
- num_target = m[1].to_i
197
+ num_bonus = m[1].to_i
198
+ num_target = m[2].to_i
160
199
 
161
- dice = @randomizer.roll_barabara(3, 6).sort
200
+ dice = @randomizer.roll_barabara(3 + num_bonus, 6).sort
162
201
  dice_text = dice.join(",")
163
202
  success_num = dice.count(num_target)
164
- is_critical = dice[0] == 1 && dice[1] == 2 && dice[2] == 3
165
- is_fumble = dice[0] == 4 && dice[1] == 5 && dice[2] == 6
203
+ is_critical = dice.include?(1) && dice.include?(2) && dice.include?(3)
204
+ is_fumble = dice.include?(4) && dice.include?(5) && dice.include?(6)
166
205
 
167
206
  return Result.new.tap do |result|
168
207
  result.critical = is_critical
@@ -170,7 +209,7 @@ module BCDice
170
209
  result.condition = (success_num > 0)
171
210
 
172
211
  sequence = [
173
- "(AG=#{num_target})",
212
+ "(#{with_symbol(num_bonus)}AG=#{num_target})",
174
213
  dice_text,
175
214
  "成功数#{success_num}",
176
215
  if result.success?
@@ -190,12 +229,13 @@ module BCDice
190
229
  # @param [String] command
191
230
  # @return [Result]
192
231
  def resolute_dodging(command)
193
- m = /^AD=(\d+)$/.match(command)
232
+ m = /^([-+]\d+)?AD=(\d+)$/.match(command)
194
233
  return nil unless m
195
234
 
196
- num_target = m[1].to_i
235
+ num_bonus = m[1].to_i
236
+ num_target = m[2].to_i
197
237
 
198
- dice = @randomizer.roll_barabara(1, 6)
238
+ dice = @randomizer.roll_barabara(1 + num_bonus, 6)
199
239
  dice_text = dice.join(",")
200
240
  success_num = dice.count(num_target)
201
241
 
@@ -203,7 +243,7 @@ module BCDice
203
243
  result.condition = (success_num > 0)
204
244
 
205
245
  sequence = [
206
- "(AD=#{num_target})",
246
+ "(#{with_symbol(num_bonus)}AD=#{num_target})",
207
247
  dice_text,
208
248
  "成功数#{success_num}",
209
249
  if result.success?
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice/game_system/Arianrhod"
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class Arianrhod_Korean < Arianrhod
8
+ # ゲームシステムの識別子
9
+ ID = 'Arianrhod:Korean'
10
+
11
+ # ゲームシステム名
12
+ NAME = '아리안로드RPG'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = '国際化:Korean:아리안로드RPG'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
19
+ ・크리티컬, 펌블의 자동판정을 행합니다.(크리티컬 시의 추가 대미지도 표시됩니다)
20
+ ・D66 다이스 있음
21
+ INFO_MESSAGE_TEXT
22
+
23
+ def initialize(command)
24
+ super(command)
25
+
26
+ @locale = :ko_kr
27
+ end
28
+
29
+ register_prefix_from_super_class()
30
+ end
31
+ end
32
+ end