diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 0fe88d638..eee765fd9 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -119,7 +119,12 @@ def rating(string) # レーティング表 currentKey = (command.rate + round * command.rateup).clamp(0, keyMax) debug("currentKey", currentKey) - rateValue = newRates[dice][currentKey] + rateValue = + if dice > command.set_zero_val + newRates[dice][currentKey] + else + 0 + end debug("rateValue", rateValue) totalValue += rateValue @@ -321,6 +326,8 @@ def rollDice(_command, _round) def getResultText(rating_total, command, diceResults, diceResultTotals, rateResults, dice_total, round) sequence = [] + critical_count = [round - 1, 0].max + additional_damage = command.add_damage * critical_count sequence.push("2D:[#{diceResults.join(' ')}]=#{diceResultTotals.join(',')}") @@ -333,6 +340,9 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, # rate回数が1回で、修正値がない時には途中式と最終結果が一致するので、途中式を省略する if rateResults.size > 1 || command.modifier != 0 text = rateResults.join(',') + Format.modifier(command.modifier) + if additional_damage != 0 + text += "+#{command.add_damage}*#{critical_count}" + end if command.half text = "(#{text})/2" if command.modifier_after_half != 0 @@ -343,6 +353,11 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, if command.modifier_after_one_and_a_half != 0 text += Format.modifier(command.modifier_after_one_and_a_half) end + elsif command.double + text = "(#{text})*2" + if command.modifier_after_double != 0 + text += Format.modifier(command.modifier_after_double) + end end sequence.push(text) elsif command.half @@ -357,6 +372,12 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, text += Format.modifier(command.modifier_after_one_and_a_half) end sequence.push(text) + elsif command.double + text = "#{rateResults.first}*2" + if command.modifier_after_double != 0 + text += Format.modifier(command.modifier_after_double) + end + sequence.push(text) end if round > 1 @@ -364,7 +385,7 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, sequence.push(round_text) end - total = rating_total + command.modifier + total = rating_total + command.modifier + additional_damage if command.half total = (total / 2.0).ceil if command.modifier_after_half != 0 @@ -375,6 +396,11 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, if command.modifier_after_one_and_a_half != 0 total += command.modifier_after_one_and_a_half end + elsif command.double + total = (total * 2).ceil + if command.modifier_after_double != 0 + total += command.modifier_after_double + end end total_text = total.to_s diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 245c61f4a..d11631b21 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -34,18 +34,25 @@ class SwordWorld2_5 < SwordWorld2_0 ・レーティング表の半減 (HKx, KxH+N)  レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。 -  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。 +  末尾につけた場合、直後に修正をつけることで、半減後の加減算を行うことができます。  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H+(1+1) ・レーティング表の1.5倍 (OHKx, KxOH+N)  レーティング表の先頭または末尾に"OH"をつけると、レーティング表を振って最終結果を1.5倍します。 -  末尾につけた場合、直後に修正ををつけることで、1.5倍後の加減算を行うことができます。 +  末尾につけた場合、直後に修正をつけることで、1.5倍後の加減算を行うことができます。  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)OHK20  K20oh  OHK10-5@9  K20+8OH+2  K20+8OH+(1+1) + ・レーティング表の2倍 (DBKx, KxDB+N) +  レーティング表の先頭または末尾に"DB"をつけると、レーティング表を振って最終結果を2倍します。 +  末尾につけた場合、直後に修正をつけることで、2倍後の加減算を行うことができます。 +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します) +  クリティカル値を指定しない場合、クリティカル値10と扱われます。 +  例)DBK20  K20db  DBK10-5@9  K20+8DB+2  K20+8DB+(1+1) + ・ダイス目の修正(運命変転やクリティカルレイ、魔女の火用)  末尾に「$修正値」でダイス目に修正がかかります。  $+1と修正表記ならダイス目に+修正、$9のように固定値ならダイス目をその出目に差し替え。 @@ -61,6 +68,9 @@ class SwordWorld2_5 < SwordWorld2_0 ・首切り刀用レーティング上昇 r5  例)K20r5 K30+24@8R5 K40+24@8$12r5 + ・肉喰む顎用クリティカルごと追加ダメージ ad2 +  例)K20ad2 K30+24@8D2 K40+24@8$12ad2 + ・グレイテストフォーチュンは末尾に gf  例)K20gf K30+24@8GF K40+24@8$12r5gf @@ -70,6 +80,9 @@ class SwordWorld2_5 < SwordWorld2_0 ・威力表を1d+tfで参照 クリティカル後は2dで参照 tf3  例)k10tf3 k0+5tf4@13 k70+26tf3@9 + ・アビスカース「難しい」用に KxSZy 表記でy以下の出目の威力表を0に書き換え。 +  例) k10SZ4 k0+5@13sz6 k40+26@9sz3 + ・超越判定用に2d6ロールに 2D6@10 書式でクリティカル値付与が可能に。  例)2D6@10 2D6@10+11>=30 @@ -96,7 +109,7 @@ class SwordWorld2_5 < SwordWorld2_0  追加アビスカース表を出すことができます。 INFO_MESSAGE_TEXT - register_prefix('H?K', 'OHK', 'Gr', '2D6?@\d+', 'FT', 'TT', 'Dru', 'Bib', 'ABT', 'AABT') + register_prefix('H?K', 'OHK', 'DBK', 'Gr', '2D6?@\d+', 'FT', 'TT', 'Dru', 'Bib', 'ABT', 'AABT') def eval_game_system_specific_command(command) case command diff --git a/lib/bcdice/game_system/sword_world/rating_options.rb b/lib/bcdice/game_system/sword_world/rating_options.rb index a981e9e4c..831cc5659 100644 --- a/lib/bcdice/game_system/sword_world/rating_options.rb +++ b/lib/bcdice/game_system/sword_world/rating_options.rb @@ -22,6 +22,9 @@ class RatingOptions # @return [Integer, nil] attr_accessor :rateup + # @return [Integer, nil] + attr_accessor :add_damage + # @return [Boolean, nil] attr_accessor :greatest_fortune @@ -31,6 +34,9 @@ class RatingOptions # @return [Integer, nil] attr_accessor :tmp_fixed_val + # @return [Integer, nil] + attr_accessor :set_zero_val + # @return [Integer, nil] attr_accessor :modifier @@ -40,6 +46,9 @@ class RatingOptions # @return [Integer, nil] attr_accessor :modifier_after_one_and_a_half + # @return [Integer, nil] + attr_accessor :modifier_after_double + def settable_first_roll_adjust_option? return first_modify.nil? && first_to.nil? && first_modify_ssp.nil? end diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index ae1305a05..2b102ff41 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -25,6 +25,9 @@ class RatingParsed # @return [Integer] attr_accessor :rateup + # @return [Integer] + attr_accessor :add_damage + # @return [Boolean] attr_accessor :greatest_fortune @@ -34,6 +37,9 @@ class RatingParsed # @return [Integer] attr_accessor :tmp_fixed_val + # @return [Integer] + attr_accessor :set_zero_val + # @return [Integer] attr_accessor :modifier @@ -43,6 +49,9 @@ class RatingParsed # @return [Integer, nil] attr_accessor :modifier_after_one_and_a_half + # @return [Integer, nil] + attr_accessor :modifier_after_double + def initialize(rate, modifier) @rate = rate @modifier = modifier @@ -53,10 +62,13 @@ def initialize(rate, modifier) @first_modify_ssp = 0 @greatest_fortune = false @rateup = 0 + @add_damage = 0 @semi_fixed_val = 0 @tmp_fixed_val = 0 + @set_zero_val = 0 @modifier_after_half = nil @modifier_after_one_and_a_half = nil + @modifier_after_double = nil end # @return [Boolean] @@ -69,6 +81,11 @@ def one_and_a_half return !@modifier_after_one_and_a_half.nil? end + # @return [Boolean] + def double + return !@modifier_after_double.nil? + end + # @return [Integer] def min_critical if @semi_fixed_val <= 1 @@ -92,9 +109,11 @@ def to_s() output += "m[~#{Format.modifier(first_modify_ssp)}]" if first_modify_ssp != 0 output += "m[#{first_to}]" if first_to != 0 output += "r[#{rateup}]" if rateup != 0 + output += "ad[#{add_damage}]" if add_damage != 0 output += "gf" if @greatest_fortune output += "sf[#{semi_fixed_val}]" if semi_fixed_val != 0 output += "tf[#{tmp_fixed_val}]" if tmp_fixed_val != 0 + output += "sz[#{set_zero_val}]" if set_zero_val != 0 output += "a[#{Format.modifier(kept_modify)}]" if kept_modify != 0 if @modifier != 0 diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 505011c86..a19ab8c25 100644 --- a/lib/bcdice/game_system/sword_world/rating_parser.y +++ b/lib/bcdice/game_system/sword_world/rating_parser.y @@ -1,5 +1,5 @@ class RatingParser - token NUMBER K R H O G F S T PLUS MINUS ASTERISK SLASH PARENL PARENR BRACKETL BRACKETR AT SHARP DOLLAR TILDE + token NUMBER K R H O D B G F S T Z A PLUS MINUS ASTERISK SLASH PARENL PARENR BRACKETL BRACKETR AT SHARP DOLLAR TILDE expect 4 @@ -13,7 +13,7 @@ class RatingParser | H rate option { _, rate, option = val - raise ParseError if option.modifier_after_one_and_a_half + raise ParseError if option.modifier_after_one_and_a_half or option.modifier_after_double option.modifier_after_half ||= Arithmetic::Node::Number.new(0) modifier = option.modifier || Arithmetic::Node::Number.new(0) result = parsed(rate, modifier.eval(@round_type), option) @@ -21,11 +21,19 @@ class RatingParser | O H rate option { _, _, rate, option = val - raise ParseError if option.modifier_after_half + raise ParseError if option.modifier_after_half or option.modifier_after_double option.modifier_after_one_and_a_half ||= Arithmetic::Node::Number.new(0) modifier = option.modifier || Arithmetic::Node::Number.new(0) result = parsed(rate, modifier.eval(@round_type), option) } + | D B rate option + { + _, _, rate, option = val + raise ParseError if option.modifier_after_half or option.modifier_after_one_and_a_half + option.modifier_after_double ||= Arithmetic::Node::Number.new(0) + modifier = option.modifier || Arithmetic::Node::Number.new(0) + result = parsed(rate, modifier.eval(@round_type), option) + } rate: K NUMBER @@ -123,6 +131,22 @@ class RatingParser option.modifier_after_one_and_a_half = term result = option } + | option D B + { + option, _, _ = val + raise ParseError unless option.modifier_after_double.nil? + + option.modifier_after_double = Arithmetic::Node::Number.new(0) + result = option + } + | option D B unary + { + option, _, _, term = val + raise ParseError unless option.modifier_after_double.nil? + + option.modifier_after_double = term + result = option + } | option R unary { option, _, term = val @@ -131,6 +155,14 @@ class RatingParser option.rateup = term result = option } + | option A D unary + { + option, _, _, term = val + raise ParseError unless [:v2_5].include?(@version) && option.add_damage.nil? + + option.add_damage = term + result = option + } | option G F { option, _, _ = val @@ -155,6 +187,14 @@ class RatingParser option.tmp_fixed_val = term.to_i result = option } + | option S Z NUMBER + { + option, _, _, term = val + raise ParseError unless [:v2_5].include?(@version) + + option.set_zero_val = term.to_i + result = option + } | option SHARP unary { option, _, term = val @@ -244,11 +284,14 @@ def parsed(rate, modifier, option) p.first_modify = option.first_modify || 0 p.first_modify_ssp = option.first_modify_ssp || 0 p.rateup = option.rateup&.eval(@round_type) || 0 + p.add_damage = option.add_damage&.eval(@round_type) || 0 p.greatest_fortune = option.greatest_fortune if !option.greatest_fortune.nil? p.semi_fixed_val = option.semi_fixed_val&.clamp(1, 6) || 0 p.tmp_fixed_val = option.tmp_fixed_val&.clamp(1, 6) || 0 + p.set_zero_val = option.set_zero_val || 0 p.modifier_after_half = option.modifier_after_half&.eval(@round_type) p.modifier_after_one_and_a_half = option.modifier_after_one_and_a_half&.eval(@round_type) + p.modifier_after_double = option.modifier_after_double&.eval(@round_type) p.critical = option.critical&.eval(@round_type)&.clamp(0, 13) || (p.half || p.one_and_a_half ? 13 : 10) end end diff --git a/test/data/SwordWorld2_5.toml b/test/data/SwordWorld2_5.toml index df67c3d4f..26bb14591 100644 --- a/test/data/SwordWorld2_5.toml +++ b/test/data/SwordWorld2_5.toml @@ -258,6 +258,131 @@ rands = [ { sides = 6, value = 2 }, ] +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20ad2" +output = "KeyNo.20c[10]ad[2] > 2D:[5,2]=7 > 5" +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20ad2" +output = "KeyNo.20c[10]ad[2] > 2D:[5,5 2,3]=10,5 > 8,3+2*1 > 1回転 > 13" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20+5#1ad2" +output = "KeyNo.20c[10]ad[2]a[+1]+5 > 2D:[5,4 2,2]=10,5 > 8,3+5+2*1 > 1回転 > 18" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 4 }, + { sides = 6, value = 2 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20$+1ad2" +output = "KeyNo.20c[10]m[+1]ad[2] > 2D:[5,4 2,2]=10,4 > 8,2+2*1 > 1回転 > 12" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 4 }, + { sides = 6, value = 2 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20$+1#1ad2" +output = "KeyNo.20c[10]m[+1]ad[2]a[+1] > 2D:[5,4 2,2]=11,5 > 9,3+2*1 > 1回転 > 14" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 4 }, + { sides = 6, value = 2 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20+5@10ad2h" +output = "KeyNo.20c[10]ad[2]+5 > 2D:[5,5 2,3]=10,5 > (8,3+5+2*1)/2 > 1回転 > 9" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20+5@10ad2oh" +output = "KeyNo.20c[10]ad[2]+5 > 2D:[5,5 2,3]=10,5 > (8,3+5+2*1)*1.5 > 1回転 > 27" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20+5@10ad2db" +output = "KeyNo.20c[10]ad[2]+5 > 2D:[5,5 2,3]=10,5 > (8,3+5+2*1)*2 > 1回転 > 36" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K40+24sf4@8$12r10#1ad2" +output = "KeyNo.40c[8]m[12]r[10]ad[2]sf[4]a[+1]+24 > 2D:[4,4 4,4 6,4 5,4 1,4]=12,9,11,10,6 > 13,12,16,18,13+24+2*4 > 4回転 > 104" +critical = true +rands = [ + { sides = 6, value = 4 }, + { sides = 6, value = 4 }, + { sides = 6, value = 6 }, + { sides = 6, value = 5 }, + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K40+24tf4@8$12r10#1ad2" +output = "KeyNo.40c[8]m[12]r[10]ad[2]tf[4]a[+1]+24 > 2D:[6,4 4,5 1,6 4,4 3,5 3,3]=12,10,8,9,9,7 > 13,13,13,17,20,18+24+2*5 > 5回転 > 128" +critical = true +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 4 }, + { sides = 6, value = 5 }, + { sides = 6, value = 1 }, + { sides = 6, value = 6 }, + { sides = 6, value = 4 }, + { sides = 6, value = 4 }, + { sides = 6, value = 3 }, + { sides = 6, value = 5 }, + { sides = 6, value = 3 }, + { sides = 6, value = 3 }, +] + [[ test ]] game_system = "SwordWorld2.5" input = "SK20+5" @@ -574,6 +699,119 @@ input = "ohk10h" output = "" rands = [] +[[ test ]] +game_system = "SwordWorld2.5" +input = "DBk10 DBKのクリティカル値は10" +output = "KeyNo.10c[10] > 2D:[6,6 5,3]=12,8 > (7,4)*2 > 1回転 > 22" +critical = true +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 6 }, + { sides = 6, value = 5 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k10db" +output = "KeyNo.10c[10] > 2D:[6,6 5,3]=12,8 > (7,4)*2 > 1回転 > 22" +critical = true +rands = [ + { sides = 6, value = 6 }, + { sides = 6, value = 6 }, + { sides = 6, value = 5 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "dbk10db" +output = "KeyNo.10c[10] > 2D:[2,6]=8 > 4*2 > 8" +rands = [ + { sides = 6, value = 2 }, + { sides = 6, value = 6 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "dbk10[9]+10" +output = "KeyNo.10c[9]+10 > 2D:[5,3]=8 > (4+10)*2 > 28" +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 3 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "dbk10[9]+10" +output = "KeyNo.10c[9]+10 > 2D:[2,4]=6 > (3+10)*2 > 26" +rands = [ + { sides = 6, value = 2 }, + { sides = 6, value = 4 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "dbK20+6@4" +output = "KeyNo.20c[4]+6 > 2D:[4,3 2,5 2,6 1,1]=7,7,8,2 > (5,5,6,**+6)*2 > 3回転 > 44" +critical = true +rands = [ + { sides = 6, value = 4 }, + { sides = 6, value = 3 }, + { sides = 6, value = 2 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 6 }, + { sides = 6, value = 1 }, + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "K20+6@4db" +output = "KeyNo.20c[4]+6 > 2D:[4,3 2,5 2,6 1,1]=7,7,8,2 > (5,5,6,**+6)*2 > 3回転 > 44" +critical = true +rands = [ + { sides = 6, value = 4 }, + { sides = 6, value = 3 }, + { sides = 6, value = 2 }, + { sides = 6, value = 5 }, + { sides = 6, value = 2 }, + { sides = 6, value = 6 }, + { sides = 6, value = 1 }, + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20db+1+1" +output = "KeyNo.20c[10]+1 > 2D:[2,6]=8 > (6+1)*2+1 > 15" +rands = [ + { sides = 6, value = 2 }, + { sides = 6, value = 6 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20db+(1+1)" +output = "KeyNo.20c[10] > 2D:[2,6]=8 > 6*2+2 > 14" +rands = [ + { sides = 6, value = 2 }, + { sides = 6, value = 6 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "dbk10oh" +output = "" +rands = [] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "ohk10db" +output = "" +rands = [] + [[ test ]] game_system = "SwordWorld2.5" input = "k20sf4 sf通常時" @@ -681,6 +919,62 @@ input = "k20sf1#8@2 クリティカル下限エラー sfが1の時の下限は3" output = "C値を3以上にしてください" rands = [] +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20+5SZ4" +output = "KeyNo.20c[10]sz[4]+5 > 2D:[5,5 1,2]=10,3 > 8,0+5 > 1回転 > 13" +critical = true +rands = [ + { sides = 6, value = 5 }, + { sides = 6, value = 5 }, + { sides = 6, value = 1 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20sz4" +output = "KeyNo.20c[10]sz[4] > 2D:[3,2]=5 > 3" +rands = [ + { sides = 6, value = 3 }, + { sides = 6, value = 2 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20tf3sz4" +output = "KeyNo.20c[10]tf[3]sz[4] > 2D:[1,3]=4 > 0" +rands = [ + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20sz4sf3" +output = "KeyNo.20c[10]sf[3]sz[4] > 2D:[1,3]=4 > 0" +rands = [ + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20$+1sz5" +output = "KeyNo.20c[10]m[+1]sz[5] > 2D:[3,1]=5 > 0" +rands = [ + { sides = 6, value = 3 }, + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "SwordWorld2.5" +input = "k20sz4" +output = "KeyNo.20c[10]sz[4] > 2D:[1,1]=2 > ** > 自動的失敗" +fumble = true +rands = [ + { sides = 6, value = 1 }, + { sides = 6, value = 1 }, +] + [[ test ]] game_system = "SwordWorld2.5" input = "2D6@10+15>=30"