bcdice 3.10.0 → 3.12.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.
- 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})",
|