From 42d2bd68687f53652faaa0f15c9018fb83f63dd2 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Tue, 17 Mar 2026 17:12:46 +0900 Subject: [PATCH 1/9] =?UTF-8?q?=E3=83=80=E3=83=A1=E3=83=BC=E3=82=B82?= =?UTF-8?q?=E5=80=8D=E5=87=A6=E7=90=86=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 16 +++ lib/bcdice/game_system/SwordWorld2_5.rb | 9 +- .../game_system/sword_world/rating_options.rb | 3 + .../game_system/sword_world/rating_parsed.rb | 9 ++ .../game_system/sword_world/rating_parser.y | 31 ++++- test/data/SwordWorld2_5.toml | 113 ++++++++++++++++++ 6 files changed, 177 insertions(+), 4 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 0fe88d638..2c8353fe8 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -343,6 +343,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 +362,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 @@ -375,6 +386,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 40df852dd..cddcdce22 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -46,6 +46,13 @@ class SwordWorld2_5 < SwordWorld2_0  クリティカル値を指定しない場合、クリティカルなしと扱われます。  例)OHK20  K20oh  OHK10-5@9  K20+8OH+2  K20+8OH+(1+1) + ・レーティング表の2倍 (DBKx, KxDB+N) +  レーティング表の先頭または末尾に"DB"をつけると、レーティング表を振って最終結果を2倍します。 +  末尾につけた場合、直後に修正ををつけることで、2倍後の加減算を行うことができます。 +  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します) +  クリティカル値を指定しない場合、クリティカルなしと扱われます。 +  例)DBK20  K20db  DBK10-5@9  K20+8DB+2  K20+8DB+(1+1) + ・ダイス目の修正(運命変転やクリティカルレイ、魔女の火用)  末尾に「$修正値」でダイス目に修正がかかります。  $+1と修正表記ならダイス目に+修正、$9のように固定値ならダイス目をその出目に差し替え。 @@ -90,7 +97,7 @@ class SwordWorld2_5 < SwordWorld2_0  アビスカース表を出すことができます。 INFO_MESSAGE_TEXT - register_prefix('H?K', 'OHK', 'Gr', '2D6?@\d+', 'FT', 'TT', 'Dru', 'ABT') + register_prefix('H?K', 'OHK', 'DBK', 'Gr', '2D6?@\d+', 'FT', 'TT', 'Dru', 'ABT') 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..bb4d82134 100644 --- a/lib/bcdice/game_system/sword_world/rating_options.rb +++ b/lib/bcdice/game_system/sword_world/rating_options.rb @@ -40,6 +40,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..ab7aaccf7 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -43,6 +43,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 @@ -57,6 +60,7 @@ def initialize(rate, modifier) @tmp_fixed_val = 0 @modifier_after_half = nil @modifier_after_one_and_a_half = nil + @modifier_after_double = nil end # @return [Boolean] @@ -69,6 +73,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 diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index 505011c86..adf0e5e8b 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 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 @@ -249,6 +273,7 @@ def parsed(rate, modifier, option) p.tmp_fixed_val = option.tmp_fixed_val&.clamp(1, 6) || 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 54b25952c..685cc978b 100644 --- a/test/data/SwordWorld2_5.toml +++ b/test/data/SwordWorld2_5.toml @@ -574,6 +574,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通常時" From 80d0390540794f28518ddb394384364847b03f51 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Tue, 17 Mar 2026 19:36:53 +0900 Subject: [PATCH 2/9] =?UTF-8?q?sz=E6=A7=8B=E6=96=87=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 6 +- lib/bcdice/game_system/SwordWorld2_5.rb | 3 + .../game_system/sword_world/rating_options.rb | 3 + .../game_system/sword_world/rating_parsed.rb | 5 ++ .../game_system/sword_world/rating_parser.y | 11 +++- test/data/SwordWorld2_5.toml | 56 +++++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 2c8353fe8..29a549c49 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -119,7 +119,11 @@ def rating(string) # レーティング表 currentKey = (command.rate + round * command.rateup).clamp(0, keyMax) debug("currentKey", currentKey) - rateValue = newRates[dice][currentKey] + if dice > command.set_zero_val + rateValue = newRates[dice][currentKey] + else + rateValue = 0 + end debug("rateValue", rateValue) totalValue += rateValue diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index cddcdce22..b92d7312e 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -77,6 +77,9 @@ class SwordWorld2_5 < SwordWorld2_0 ・威力表を1d+tfで参照 クリティカル後は2dで参照 tf3  例)k10tf3 k0+5tf4@13 k70+26tf3@9 + ・アビスカース「難しい」用にある出目以下の威力表を0に書き換え sz4 +  例) k10SZ4 k0+5@13sz6 k40+26@9sz3 + ・超越判定用に2d6ロールに 2D6@10 書式でクリティカル値付与が可能に。  例)2D6@10 2D6@10+11>=30 diff --git a/lib/bcdice/game_system/sword_world/rating_options.rb b/lib/bcdice/game_system/sword_world/rating_options.rb index bb4d82134..9a550797e 100644 --- a/lib/bcdice/game_system/sword_world/rating_options.rb +++ b/lib/bcdice/game_system/sword_world/rating_options.rb @@ -31,6 +31,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 diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index ab7aaccf7..e9a55287e 100644 --- a/lib/bcdice/game_system/sword_world/rating_parsed.rb +++ b/lib/bcdice/game_system/sword_world/rating_parsed.rb @@ -34,6 +34,9 @@ class RatingParsed # @return [Integer] attr_accessor :tmp_fixed_val + # @return [Integer] + attr_accessor :set_zero_val + # @return [Integer] attr_accessor :modifier @@ -58,6 +61,7 @@ def initialize(rate, modifier) @rateup = 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 @@ -104,6 +108,7 @@ def to_s() 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 adf0e5e8b..dcff44546 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 D B 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 PLUS MINUS ASTERISK SLASH PARENL PARENR BRACKETL BRACKETR AT SHARP DOLLAR TILDE expect 4 @@ -179,6 +179,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 @@ -271,6 +279,7 @@ def parsed(rate, modifier, option) 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) diff --git a/test/data/SwordWorld2_5.toml b/test/data/SwordWorld2_5.toml index 685cc978b..14edd1dfc 100644 --- a/test/data/SwordWorld2_5.toml +++ b/test/data/SwordWorld2_5.toml @@ -794,6 +794,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" From 85c90ecbb4ceba4b5c274ebffd1be399342a3988 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Tue, 17 Mar 2026 20:11:01 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=E8=AA=AC=E6=98=8E=E6=96=87=E3=82=92?= =?UTF-8?q?=E7=B7=A8=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_5.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index b92d7312e..4d09db8eb 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -50,7 +50,7 @@ class SwordWorld2_5 < SwordWorld2_0  レーティング表の先頭または末尾に"DB"をつけると、レーティング表を振って最終結果を2倍します。  末尾につけた場合、直後に修正ををつけることで、2倍後の加減算を行うことができます。  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します) -  クリティカル値を指定しない場合、クリティカルなしと扱われます。 +  クリティカル値を指定しない場合、クリティカル値10と扱われます。  例)DBK20  K20db  DBK10-5@9  K20+8DB+2  K20+8DB+(1+1) ・ダイス目の修正(運命変転やクリティカルレイ、魔女の火用) From 411a8e22aaea4db071999a2c253c5e91716650f1 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Tue, 17 Mar 2026 20:16:36 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=E8=A1=8D=E5=AD=97=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_5.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 4d09db8eb..15bf323da 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -34,21 +34,21 @@ 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倍後の加減算を行うことができます。 +  末尾につけた場合、直後に修正をつけることで、2倍後の加減算を行うことができます。  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)  クリティカル値を指定しない場合、クリティカル値10と扱われます。  例)DBK20  K20db  DBK10-5@9  K20+8DB+2  K20+8DB+(1+1) From b644c795f1eae4d030ae6962994b24c63c69abca Mon Sep 17 00:00:00 2001 From: neutron317 Date: Tue, 17 Mar 2026 22:37:33 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=E8=AA=AC=E6=98=8E=E6=96=87=E3=82=92?= =?UTF-8?q?=E7=B7=A8=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld2_5.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 15bf323da..62cc48e38 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -77,7 +77,7 @@ class SwordWorld2_5 < SwordWorld2_0 ・威力表を1d+tfで参照 クリティカル後は2dで参照 tf3  例)k10tf3 k0+5tf4@13 k70+26tf3@9 - ・アビスカース「難しい」用にある出目以下の威力表を0に書き換え sz4 + ・アビスカース「難しい」用に KxSZy 表記でy以下の出目の威力表を0に書き換え。  例) k10SZ4 k0+5@13sz6 k40+26@9sz3 ・超越判定用に2d6ロールに 2D6@10 書式でクリティカル値付与が可能に。 From 09e597a9083da1be2adf1147eaa87a361abfb332 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Wed, 25 Mar 2026 21:18:16 +0900 Subject: [PATCH 6/9] =?UTF-8?q?add=5Fdamage=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 9 +- lib/bcdice/game_system/SwordWorld2_5.rb | 3 + .../game_system/sword_world/rating_options.rb | 3 + .../game_system/sword_world/rating_parsed.rb | 5 + .../game_system/sword_world/rating_parser.y | 11 +- test/data/SwordWorld2_5.toml | 125 ++++++++++++++++++ 6 files changed, 153 insertions(+), 3 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 29a549c49..8ee65f4f0 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -325,6 +325,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(',')}") @@ -335,8 +337,11 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, end # rate回数が1回で、修正値がない時には途中式と最終結果が一致するので、途中式を省略する - if rateResults.size > 1 || command.modifier != 0 + if rateResults.size > 1 || command.modifier != 0 || additional_damage != 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 @@ -379,7 +384,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 diff --git a/lib/bcdice/game_system/SwordWorld2_5.rb b/lib/bcdice/game_system/SwordWorld2_5.rb index 62cc48e38..364c3b285 100644 --- a/lib/bcdice/game_system/SwordWorld2_5.rb +++ b/lib/bcdice/game_system/SwordWorld2_5.rb @@ -68,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 diff --git a/lib/bcdice/game_system/sword_world/rating_options.rb b/lib/bcdice/game_system/sword_world/rating_options.rb index 9a550797e..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 diff --git a/lib/bcdice/game_system/sword_world/rating_parsed.rb b/lib/bcdice/game_system/sword_world/rating_parsed.rb index e9a55287e..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 @@ -59,6 +62,7 @@ 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 @@ -105,6 +109,7 @@ 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 diff --git a/lib/bcdice/game_system/sword_world/rating_parser.y b/lib/bcdice/game_system/sword_world/rating_parser.y index dcff44546..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 D B G F S T Z 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 @@ -155,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 @@ -276,6 +284,7 @@ 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 diff --git a/test/data/SwordWorld2_5.toml b/test/data/SwordWorld2_5.toml index 14edd1dfc..16ccb4f36 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" From 7bb3737b853a4b50455924f72b194f01486c8ff1 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Wed, 25 Mar 2026 21:24:37 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=E5=86=97=E9=95=B7=E3=81=AA=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 8ee65f4f0..574c8649d 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -337,7 +337,7 @@ def getResultText(rating_total, command, diceResults, diceResultTotals, end # rate回数が1回で、修正値がない時には途中式と最終結果が一致するので、途中式を省略する - if rateResults.size > 1 || command.modifier != 0 || additional_damage != 0 + if rateResults.size > 1 || command.modifier != 0 text = rateResults.join(',') + Format.modifier(command.modifier) if additional_damage != 0 text += "+#{command.add_damage}*#{critical_count}" From b62360ab6b155105b996b4710475e7fcb066b17f Mon Sep 17 00:00:00 2001 From: neutron317 Date: Thu, 9 Apr 2026 20:53:32 +0900 Subject: [PATCH 8/9] =?UTF-8?q?rateValue=E3=81=AE=E5=AE=9A=E7=BE=A9?= =?UTF-8?q?=E3=81=AE=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA?= =?UTF-8?q?=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: SAKATA Sinji --- lib/bcdice/game_system/SwordWorld.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index 574c8649d..a42115e75 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -119,11 +119,12 @@ def rating(string) # レーティング表 currentKey = (command.rate + round * command.rateup).clamp(0, keyMax) debug("currentKey", currentKey) - if dice > command.set_zero_val - rateValue = newRates[dice][currentKey] - else - rateValue = 0 - end + rateValue = + if dice > command.set_zero_val + newRates[dice][currentKey] + else + 0 + end debug("rateValue", rateValue) totalValue += rateValue From 62cb1f74502c5900e1e3002fe3ea5e917e677eb3 Mon Sep 17 00:00:00 2001 From: neutron317 Date: Thu, 9 Apr 2026 21:04:33 +0900 Subject: [PATCH 9/9] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E6=95=B4?= =?UTF-8?q?=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bcdice/game_system/SwordWorld.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bcdice/game_system/SwordWorld.rb b/lib/bcdice/game_system/SwordWorld.rb index a42115e75..eee765fd9 100644 --- a/lib/bcdice/game_system/SwordWorld.rb +++ b/lib/bcdice/game_system/SwordWorld.rb @@ -119,7 +119,7 @@ def rating(string) # レーティング表 currentKey = (command.rate + round * command.rateup).clamp(0, keyMax) debug("currentKey", currentKey) - rateValue = + rateValue = if dice > command.set_zero_val newRates[dice][currentKey] else