bcdice 3.10.0 → 3.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/i18n/FutariSousa/ko_kr.yml +1625 -529
- data/i18n/Insane/ko_kr.yml +393 -258
- data/i18n/NinjaSlayer2/ja_jp.yml +34 -0
- data/lib/bcdice/game_system/DemonSpike.rb +89 -0
- data/lib/bcdice/game_system/Emoklore.rb +4 -6
- data/lib/bcdice/game_system/FutariSousa_Korean.rb +44 -19
- data/lib/bcdice/game_system/GundamSentinel.rb +377 -0
- data/lib/bcdice/game_system/HunterTheReckoning5th.rb +10 -3
- data/lib/bcdice/game_system/Insane_Korean.rb +11 -11
- data/lib/bcdice/game_system/KamitsubakiCityUnderConstructionNarrative.rb +251 -0
- data/lib/bcdice/game_system/MamonoScramble.rb +98 -0
- data/lib/bcdice/game_system/NinjaSlayer.rb +3 -1
- data/lib/bcdice/game_system/NinjaSlayer2.rb +299 -0
- data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +170 -0
- data/lib/bcdice/game_system/SajinsenkiAGuS.rb +5 -1
- data/lib/bcdice/game_system/SajinsenkiAGuS2E.rb +285 -0
- data/lib/bcdice/game_system/SkynautsBouken.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +16 -0
- data/lib/bcdice/game_system/SwordWorld2_5.rb +8 -1
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +10 -4
- data/lib/bcdice/game_system/WerewolfTheApocalypse5th.rb +173 -0
- data/lib/bcdice/game_system/ZombiLine.rb +115 -0
- data/lib/bcdice/game_system/sword_world/rating_options.rb +3 -0
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +9 -0
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +173 -128
- data/lib/bcdice/game_system/sword_world/transcendent_test.rb +1 -1
- data/lib/bcdice/game_system.rb +9 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +13 -3
@@ -0,0 +1,299 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class NinjaSlayer2 < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = "NinjaSlayer2"
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = "ニンジャスレイヤーTRPG 2版"
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = "にんしやすれいやあTRPG2"
|
14
|
+
|
15
|
+
HELP_MESSAGE = <<~TEXT
|
16
|
+
- K{x1},{x2},...,{xn}
|
17
|
+
難易度K([K]ids)の成功判定({x1}B6>=2)を、ダイス{x1}個({x2}~を指定した場合はそれぞれ個々に)で実行します。
|
18
|
+
先頭の文字を変えることで、難易度E([E]asy),N([N]ormal),H([H]ard),U([U]ltra-hard)もしくはUH([U]ltra-[H]ard)でも実行可能です。(以下も同様)
|
19
|
+
|
20
|
+
- K{x1},{x2},...,{xn}[>={y}]
|
21
|
+
K{x1}のロールの結果を使って、[]内で指定された条件を満たすダイスの個数を追加で出力します。
|
22
|
+
判定式は「>=」の他に「>」「<=」「<」「=」「!=」が利用可能です。
|
23
|
+
[=5][=6]のように複数記述することで、それぞれで追加判定が可能です。
|
24
|
+
|
25
|
+
- K{x1},{x2},...,{xn}[S] or K{x1},{x2},...,{xn}[S{y}]
|
26
|
+
- K{x1},{x2},...,{xn}[C] or K{x1},{x2},...,{xn}[C{y}]
|
27
|
+
いずれもK{x1},{x2},...,{xn}[>={y}]のショートカットです。({y}省略時は固定値6で処理します。)
|
28
|
+
出力時のテキストが、Sの場合は「サツバツ!」に、Cの場合は「クリティカル!」になります。
|
29
|
+
こちらも複数記述することで、それぞれで追加判定が可能です。
|
30
|
+
|
31
|
+
- SB or SB@{x}
|
32
|
+
{x}(1-6/省略時はd6)に対応したサツバツ([S]atz-[B]atz)・クリティカル表の内容を返します。
|
33
|
+
|
34
|
+
- WS{x}
|
35
|
+
{x}(1-12/省略不可)に対応する[W]as[s]hoi!判定(2d6<={x})を行います
|
36
|
+
|
37
|
+
- WSE or WSE@{x}
|
38
|
+
{x}(1-6/省略時はd6)に対応する死神のエントリー決定表([W]as[s]hoi! [E]ntry)の内容を返します。
|
39
|
+
|
40
|
+
- NRS_E{x} or NRS_E{x}@{y} or NRS@{y}
|
41
|
+
ダイス{x}個で難易度[E]asy(>=3)のNRS判定({x}省略時はスキップ)を行い、失敗した場合は{y}(1~7/省略時は難易度に応じたダイス目)に対応するNRS発狂表を返します。
|
42
|
+
「_E」部分を変更することで、難易度N,H,U,UHでも利用可能です。(Kはありません)
|
43
|
+
TEXT
|
44
|
+
|
45
|
+
# Base::eval_game_system_specific_commandの実装
|
46
|
+
# @param command [String]
|
47
|
+
# @return [String, nil]
|
48
|
+
def eval_game_system_specific_command(command)
|
49
|
+
# @debug = true
|
50
|
+
debug("input: #{command}")
|
51
|
+
|
52
|
+
begin
|
53
|
+
case command
|
54
|
+
when RE_JUDGE_DICEROLL
|
55
|
+
# 2版用のダイス判定
|
56
|
+
proc_result = proc_dice_2nd(Regexp.last_match)
|
57
|
+
|
58
|
+
# 結果は文字列と達成値という形で受け取る
|
59
|
+
if proc_result[1] > 0
|
60
|
+
return Result.success(proc_result[0])
|
61
|
+
else
|
62
|
+
return Result.failure(proc_result[0])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
# ダイスでなければ定型文処理
|
66
|
+
return proc_text(command)
|
67
|
+
end
|
68
|
+
rescue StandardError => e
|
69
|
+
# 解析できずにエラーが出たら構文ミスと皆してnilを返す
|
70
|
+
debug("#{e.message} \n#{e.backtrace}")
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# 文字列stringを数値化する。nilの場合はdefaultで指定された値を返す
|
78
|
+
# @param string [String]
|
79
|
+
# @param default [Integer]
|
80
|
+
# @return [Integer]
|
81
|
+
def s_to_i(string, default)
|
82
|
+
return string.nil? ? default : string.to_i
|
83
|
+
end
|
84
|
+
|
85
|
+
# 判定結果の出力テキストと成功数のカウントを返す。
|
86
|
+
# @param dice_array [Array<Integer>]
|
87
|
+
# @param difficulty [Integer]
|
88
|
+
# @param cmp_op [String]
|
89
|
+
# @param title_text [String]
|
90
|
+
# @return [String, Integer]
|
91
|
+
def check_difficulty(dice_array, difficulty, cmp_op, title_text)
|
92
|
+
success_num = 0
|
93
|
+
success_dice = []
|
94
|
+
dice_array.each do |dice_value|
|
95
|
+
if dice_value.send(Normalize.comparison_operator(cmp_op), difficulty)
|
96
|
+
success_num += 1
|
97
|
+
success_dice.push(dice_value)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
success_dice_s = success_dice.empty? ? "" : "[#{success_dice.sort.reverse.join(',')}]"
|
102
|
+
return "#{title_text}:#{success_num}#{success_dice_s}", success_num
|
103
|
+
end
|
104
|
+
|
105
|
+
# ダイス処理(2版用)
|
106
|
+
# @param command [String]
|
107
|
+
# @return [String, Integer]
|
108
|
+
def proc_dice_2nd(match)
|
109
|
+
output_text = ''
|
110
|
+
total_success_num = 0
|
111
|
+
|
112
|
+
difficulty = DIFFICULTY_SYMBOL_TO_INTEGER.fetch(match[1])
|
113
|
+
appendix = match[3]
|
114
|
+
|
115
|
+
match[2].split(",").each do |sub_command|
|
116
|
+
dice_num = sub_command.to_i
|
117
|
+
|
118
|
+
# D6バラバラロール
|
119
|
+
roll_command = "#{dice_num}B6>=#{difficulty}"
|
120
|
+
roll_result = BCDice::CommonCommand::BarabaraDice.eval(roll_command, self, @randomizer)
|
121
|
+
|
122
|
+
output_text += "(#{roll_command}) > #{roll_result.last_dice_list.join(',')} > 成功数:#{roll_result.success_num}"
|
123
|
+
success_num = roll_result.success_num
|
124
|
+
|
125
|
+
# Appendix部分の処理
|
126
|
+
unless appendix.nil?
|
127
|
+
debug("---- appendix: [#{appendix}]")
|
128
|
+
ap_command_array = appendix.split("\]\[")
|
129
|
+
ap_command_array.each do |ap_command|
|
130
|
+
debug("----- ap_command: #{ap_command}")
|
131
|
+
case ap_command
|
132
|
+
when RE_COUNT_SATZ_BATZ
|
133
|
+
# サツバツ!カウント
|
134
|
+
check_result = check_difficulty(roll_result.last_dice_list, s_to_i(Regexp.last_match[1], 6), ">=", "サツバツ!")
|
135
|
+
output_text += ", #{check_result[0]}"
|
136
|
+
success_num += check_result[1]
|
137
|
+
when RE_COUNT_CRITICAL
|
138
|
+
# クリティカル!カウント
|
139
|
+
check_result = check_difficulty(roll_result.last_dice_list, s_to_i(Regexp.last_match[1], 6), ">=", "クリティカル!")
|
140
|
+
output_text += ", #{check_result[0]}"
|
141
|
+
success_num += check_result[1]
|
142
|
+
when RE_COUNT_JUDGE
|
143
|
+
# 追加判定カウント
|
144
|
+
check_result = check_difficulty(roll_result.last_dice_list, Regexp.last_match[2].to_i, Regexp.last_match[1], "追加判定")
|
145
|
+
output_text += ", #{check_result[0]}"
|
146
|
+
success_num += check_result[1]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
output_text += " \n"
|
151
|
+
|
152
|
+
total_success_num += success_num
|
153
|
+
end
|
154
|
+
|
155
|
+
return output_text, total_success_num
|
156
|
+
end
|
157
|
+
|
158
|
+
# サツバツ!の処理を実行する
|
159
|
+
# @param type [Integer]
|
160
|
+
# @return [Result]
|
161
|
+
def proc_satz_batz(type)
|
162
|
+
# サツバツ判定(d6)
|
163
|
+
if type > 0
|
164
|
+
return "サツバツ!!(#{type}) > #{translate('NinjaSlayer2.table.SATSUBATSU.items')[type - 1]}"
|
165
|
+
else
|
166
|
+
return DiceTable::Table.from_i18n("NinjaSlayer2.table.SATSUBATSU", @locale).roll(@randomizer)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Wasshoi!判定の処理を実行する
|
171
|
+
# @param dkk [Integer]
|
172
|
+
# @return [Result]
|
173
|
+
def proc_wasshoi(dkk)
|
174
|
+
dice_array = @randomizer.roll_barabara(2, 6)
|
175
|
+
output_text = "Wasshoi!判定(2D6) > (#{dice_array.join('+')}) > #{dice_array.sum()}"
|
176
|
+
|
177
|
+
if dice_array.sum() > dkk
|
178
|
+
output_text += "(>#{dkk}) 判定失敗"
|
179
|
+
return Result.success(output_text)
|
180
|
+
else
|
181
|
+
output_text += "(<=#{dkk}) 判定成功!! \nニンジャスレイヤー=サンのエントリーだ!!"
|
182
|
+
return Result.failure(output_text)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Wasshoi!の処理を実行する
|
187
|
+
# @param type [Integer]
|
188
|
+
# @return [Result]
|
189
|
+
def proc_wasshoi_entry(type)
|
190
|
+
# Wasshoi!判定
|
191
|
+
output_text = ""
|
192
|
+
if type > 0
|
193
|
+
output_text += "ニンジャスレイヤー=サンのエントリー!!(#{type}) > #{translate('NinjaSlayer2.table.WASSHOI.items')[type - 1]}"
|
194
|
+
else
|
195
|
+
# DKKの指定無し、もしくはロール結果がDKKを超えたら死神のエントリー決定表(d6)
|
196
|
+
table = DiceTable::Table.from_i18n("NinjaSlayer2.table.WASSHOI", @locale)
|
197
|
+
output_text += table.roll(@randomizer).to_s
|
198
|
+
end
|
199
|
+
return output_text
|
200
|
+
end
|
201
|
+
|
202
|
+
# NRS判定の処理を実行する
|
203
|
+
# @param dice_num [Integer]
|
204
|
+
# @param dificulty_s [String]
|
205
|
+
# @param type [Integer]
|
206
|
+
# @return [Result]
|
207
|
+
def proc_nrs(dice_num, dificulty_s, type)
|
208
|
+
# 難易度も乱数表の番号も指定が無ければコマンドミス
|
209
|
+
dificulty_i = dificulty_s.nil? ? 0 : DIFFICULTY_SYMBOL_TO_INTEGER.fetch(dificulty_s)
|
210
|
+
if dificulty_i == 0 && type == 0
|
211
|
+
return nil
|
212
|
+
end
|
213
|
+
|
214
|
+
# NRS判定
|
215
|
+
output_text = ""
|
216
|
+
if dificulty_i > 0
|
217
|
+
roll_command = "#{dice_num}B6>=#{dificulty_i}"
|
218
|
+
roll_result = BCDice::CommonCommand::BarabaraDice.eval(roll_command, self, @randomizer)
|
219
|
+
output_text += "NRS判定(#{roll_command}) > #{roll_result.last_dice_list.join(',')} > 成功数:#{roll_result.success_num}"
|
220
|
+
if roll_result.success_num > 0
|
221
|
+
output_text += " NRS克服!!"
|
222
|
+
return Result.success(output_text)
|
223
|
+
else
|
224
|
+
output_text += " NRS発症!! \n"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# NRS発狂表の決定
|
229
|
+
dice_face = 0
|
230
|
+
additional = 0
|
231
|
+
if type == 0
|
232
|
+
case dificulty_s
|
233
|
+
when "E"
|
234
|
+
dice_face = 3
|
235
|
+
when "N"
|
236
|
+
dice_face = 6
|
237
|
+
when "H", "U"
|
238
|
+
dice_face = 6
|
239
|
+
additional = 1
|
240
|
+
end
|
241
|
+
type = @randomizer.roll_once(dice_face) + additional
|
242
|
+
end
|
243
|
+
roll_command = "1D#{dice_face}#{additional > 0 ? '+' + additional.to_s : ''}"
|
244
|
+
output_text += "NRS発狂#{dice_face > 0 ? "(#{roll_command}) > " : ''}(#{type}) > #{translate('NinjaSlayer2.table.NRS.items')[type - 1]}"
|
245
|
+
return Result.failure(output_text)
|
246
|
+
end
|
247
|
+
|
248
|
+
# テキスト系処理
|
249
|
+
# @param command [String]
|
250
|
+
# @return [String, Integer]
|
251
|
+
def proc_text(command)
|
252
|
+
debug("text: #{command}")
|
253
|
+
case command
|
254
|
+
when RE_JUDGE_SATZ_BATZ
|
255
|
+
# サツバツ判定(d6)
|
256
|
+
return proc_satz_batz(Regexp.last_match[1].to_i)
|
257
|
+
when RE_JUDGE_WASSHOI
|
258
|
+
# Wasshoi!判定
|
259
|
+
return proc_wasshoi(Regexp.last_match[1].to_i)
|
260
|
+
when RE_JUDGE_WASSHOI_ENTRY
|
261
|
+
# Wasshoi!判定
|
262
|
+
return proc_wasshoi_entry(Regexp.last_match[1].to_i)
|
263
|
+
when RE_JUDGE_NRS
|
264
|
+
# NRS判定
|
265
|
+
return proc_nrs(Regexp.last_match[2].to_i, Regexp.last_match[1], Regexp.last_match[3].to_i)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
RE_COUNT_SATZ_BATZ = /S([1-6])?/i.freeze
|
270
|
+
RE_COUNT_CRITICAL = /C([1-6])?/i.freeze
|
271
|
+
RE_COUNT_JUDGE = /(=|!=|>=|>|<=|<)([1-6])/.freeze
|
272
|
+
|
273
|
+
RE_JUDGE_DICEROLL = /^(UH|[KENHU])([\d,]+)(?:\[((?:(?:S([1-6])?|C([1-6])?|(=|!=|>=|>|<=|<)([1-6]))(?:\]\[)?)+)\])?$/i.freeze
|
274
|
+
RE_JUDGE_SATZ_BATZ = /^SB(?:@([1-6]))?$/i.freeze
|
275
|
+
RE_JUDGE_WASSHOI = /^WS([1-9]|10|11|12)$/i.freeze
|
276
|
+
RE_JUDGE_WASSHOI_ENTRY = /^WSE(?:@([1-6]))?$/i.freeze
|
277
|
+
RE_JUDGE_NRS = /^NRS(?:_(E|N|H|U|UH)(\d+))?(?:@([1-7]))?$/i.freeze
|
278
|
+
|
279
|
+
# 難易度の文字表現から整数値への対応
|
280
|
+
DIFFICULTY_SYMBOL_TO_INTEGER = {
|
281
|
+
'K' => 2,
|
282
|
+
'E' => 3,
|
283
|
+
'N' => 4,
|
284
|
+
'H' => 5,
|
285
|
+
'U' => 6,
|
286
|
+
'UH' => 6
|
287
|
+
}.freeze
|
288
|
+
|
289
|
+
register_prefix(
|
290
|
+
"UH",
|
291
|
+
"[KENHU]",
|
292
|
+
"SB",
|
293
|
+
"WS",
|
294
|
+
"WSE",
|
295
|
+
"NRS"
|
296
|
+
)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class RuneQuestRoleplayingInGlorantha < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'RuneQuestRoleplayingInGlorantha'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = 'RuneQuest:Roleplaying in Glorantha'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'るうんくえすと4'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~MESSAGETEXT
|
17
|
+
・判定コマンド クリティカル、スペシャル、ファンブルを含めた判定を行う。
|
18
|
+
RQG<=成功率
|
19
|
+
|
20
|
+
例1:RQG<=80 (技能値80で判定)
|
21
|
+
例2:RQG<=80+20 (技能値100で判定)
|
22
|
+
|
23
|
+
・抵抗判定コマンド(能動-受動) クリティカル、スペシャル、ファンブルを含めた判定を行う。
|
24
|
+
RES(能動能力-受動能力)m増強値
|
25
|
+
増強値は省略可能。
|
26
|
+
|
27
|
+
例1:RES(9-11) (能動能力9 vs 受動能力11で判定)
|
28
|
+
例2:RES(9-11)m20 (能動能力9 vs 受動能力11、+20%の増強が能動側に入る判定)
|
29
|
+
例3:RES(9)m50 (能動能力と受動能力の差が9で、+50%の増強が能動側に入る判定)
|
30
|
+
|
31
|
+
・抵抗判定コマンド(能動側のみ) クリティカル、スペシャル、ファンブルは含めず判定を行う。
|
32
|
+
RSA(能動能力)m増強値
|
33
|
+
増強値は省略可能。
|
34
|
+
|
35
|
+
例1:RSA(9) (能動能力9で判定)
|
36
|
+
例2:RSA(9)m20 (能動能力9で判定、+20%の増強が能動側に入る判定)
|
37
|
+
|
38
|
+
MESSAGETEXT
|
39
|
+
|
40
|
+
register_prefix('RQG', 'RES', 'RSA')
|
41
|
+
|
42
|
+
def eval_game_system_specific_command(command)
|
43
|
+
case command
|
44
|
+
when /RQG/i
|
45
|
+
return do_ability_roll(command)
|
46
|
+
when /RES/i
|
47
|
+
return do_resistance_roll(command)
|
48
|
+
when /RSA/i
|
49
|
+
return do_resistance_active_characteristic_roll(command)
|
50
|
+
end
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# 技能などの一般判定
|
57
|
+
def do_ability_roll(command)
|
58
|
+
m = %r{\A(RQG)(<=([+-/*\d]+))?$}.match(command)
|
59
|
+
unless m
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
|
63
|
+
roll_value = @randomizer.roll_once(100)
|
64
|
+
unless m[3]
|
65
|
+
# RQGのみ指定された場合は1d100を振ったのと同じ挙動
|
66
|
+
return "(1D100) > #{roll_value}"
|
67
|
+
end
|
68
|
+
|
69
|
+
ability_value = Arithmetic.eval(m[3], RoundType::ROUND)
|
70
|
+
result_prefix_str = "(1D100<=#{ability_value}) >"
|
71
|
+
|
72
|
+
if ability_value == 0
|
73
|
+
# 0%は判定なしで失敗
|
74
|
+
return Result.failure("#{result_prefix_str} 失敗")
|
75
|
+
end
|
76
|
+
|
77
|
+
result_str = "#{result_prefix_str} #{roll_value} >"
|
78
|
+
|
79
|
+
# 判定
|
80
|
+
get_roll_result(result_str, ability_value, roll_value)
|
81
|
+
end
|
82
|
+
|
83
|
+
# 抵抗判定
|
84
|
+
def do_resistance_roll(command)
|
85
|
+
m = %r{\A(RES)([+-/*\d]+)(M([+-/*\d]+))?$}.match(command)
|
86
|
+
unless m
|
87
|
+
return nil
|
88
|
+
end
|
89
|
+
|
90
|
+
unless m[2]
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
|
94
|
+
difference_value = Arithmetic.eval(m[2], RoundType::ROUND)
|
95
|
+
difference_value = -10 if difference_value < -10
|
96
|
+
|
97
|
+
resistance_velue = 50 + (difference_value * 5)
|
98
|
+
resistance_velue += Arithmetic.eval(m[4], RoundType::ROUND) if m[4]
|
99
|
+
|
100
|
+
roll_value = @randomizer.roll_once(100)
|
101
|
+
result_str = "(1D100<=#{resistance_velue}) > #{roll_value} >"
|
102
|
+
|
103
|
+
# 判定
|
104
|
+
get_roll_result(result_str, resistance_velue, roll_value)
|
105
|
+
end
|
106
|
+
|
107
|
+
# 能動側のみの対抗判定
|
108
|
+
def do_resistance_active_characteristic_roll(command)
|
109
|
+
m = %r{\A(RSA)(\d+)(M([+-/*\d]+))?$}.match(command)
|
110
|
+
unless m
|
111
|
+
return nil
|
112
|
+
end
|
113
|
+
|
114
|
+
unless m[2]
|
115
|
+
return nil
|
116
|
+
end
|
117
|
+
|
118
|
+
active_ability_value = m[2].to_i
|
119
|
+
if active_ability_value == 0
|
120
|
+
return "0は指定できません。"
|
121
|
+
end
|
122
|
+
|
123
|
+
modifiy_value = m[4] ? Arithmetic.eval(m[4], RoundType::ROUND) : 0
|
124
|
+
roll_value = @randomizer.roll_once(100)
|
125
|
+
active_value = active_ability_value * 5 + modifiy_value
|
126
|
+
result_prefix_str = "(1D100<=#{active_value}) > #{roll_value} >"
|
127
|
+
|
128
|
+
note_str = "クリティカル/スペシャル、ファンブルは未処理。必要なら確認すること。"
|
129
|
+
|
130
|
+
if roll_value >= 96
|
131
|
+
# 96以上は無条件で失敗
|
132
|
+
Result.failure("#{result_prefix_str} 失敗\n#{note_str}")
|
133
|
+
elsif roll_value <= 5 || roll_value <= modifiy_value
|
134
|
+
# 05以下あるいは修正値以下は無条件で成功
|
135
|
+
Result.success("#{result_prefix_str} 成功\n#{note_str}")
|
136
|
+
else
|
137
|
+
# 上記全てが当てはまらない時に突破可能な能力値を算出
|
138
|
+
"#{result_prefix_str} 相手側能力値#{active_ability_value + (50 + modifiy_value - roll_value) / 5}まで成功\n#{note_str}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# 判定結果の取得
|
143
|
+
def get_roll_result(result_str, success_value, roll_value)
|
144
|
+
critical_value = (success_value.to_f / 20).round
|
145
|
+
special_value = (success_value.to_f / 5).round
|
146
|
+
funmble_value = ((100 - success_value.to_f) / 20).round
|
147
|
+
|
148
|
+
if (roll_value == 1) || (roll_value <= critical_value)
|
149
|
+
# クリティカル(01は必ずクリティカル)
|
150
|
+
Result.critical("#{result_str} クリティカル/スペシャル")
|
151
|
+
elsif (roll_value == 100) || (roll_value >= (100 - funmble_value + 1))
|
152
|
+
# ファンブル(00は必ずファンブル)
|
153
|
+
Result.fumble("#{result_str} ファンブル")
|
154
|
+
elsif roll_value >= 96 || ((roll_value > success_value) && (roll_value > 5))
|
155
|
+
# 失敗(96以上は必ず失敗、出目が01-05ではなく技能値より上なら失敗)
|
156
|
+
Result.failure("#{result_str} 失敗")
|
157
|
+
elsif roll_value <= special_value
|
158
|
+
# スペシャル
|
159
|
+
Result.success("#{result_str} スペシャル")
|
160
|
+
elsif (roll_value <= 5) || (roll_value <= success_value)
|
161
|
+
# 成功(05以下は必ず成功)
|
162
|
+
Result.success("#{result_str} 成功")
|
163
|
+
else
|
164
|
+
# ここには到達しないはずだが、念のため捕捉
|
165
|
+
Result.failure("#{result_str} エラー")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -51,15 +51,17 @@ module BCDice
|
|
51
51
|
|
52
52
|
dice_list = @randomizer.roll_barabara(2, 10).map { |d| d == 10 ? 0 : d }
|
53
53
|
total = dice_list.sum
|
54
|
+
success_level = 1 + dice_list.count { |val| val <= level }
|
54
55
|
|
55
56
|
return Result.new.tap do |result|
|
56
57
|
result.condition = total <= target
|
58
|
+
result.rands = dice_list
|
57
59
|
|
58
60
|
sequence = [
|
59
61
|
"(2D10<=#{target})",
|
60
62
|
"#{total}[#{dice_list.join(',')}]",
|
61
63
|
("チャンス" if dice_list.include?(0)),
|
62
|
-
result.success? ? "成功" : "失敗"
|
64
|
+
result.success? ? "成功(+#{success_level})" : "失敗"
|
63
65
|
].compact
|
64
66
|
|
65
67
|
result.text = sequence.join(" > ")
|
@@ -91,6 +93,7 @@ module BCDice
|
|
91
93
|
|
92
94
|
return Result.new.tap do |r|
|
93
95
|
r.condition = total <= target
|
96
|
+
r.rands = dice_list
|
94
97
|
r.critical = criticals >= 1
|
95
98
|
r.text = [
|
96
99
|
"(2D10<=#{target})",
|
@@ -114,6 +117,7 @@ module BCDice
|
|
114
117
|
|
115
118
|
return Result.new.tap do |r|
|
116
119
|
r.condition = total <= target
|
120
|
+
r.rands = dice_list
|
117
121
|
r.critical = criticals >= 1
|
118
122
|
r.text = [
|
119
123
|
"(3D10<=#{target})",
|