diff --git a/lib/bcdice/game_system/ArknightsFan.rb b/lib/bcdice/game_system/ArknightsFan.rb index 0b552afc3..0e6cd358a 100644 --- a/lib/bcdice/game_system/ArknightsFan.rb +++ b/lib/bcdice/game_system/ArknightsFan.rb @@ -13,25 +13,38 @@ class ArknightsFan < Base SORT_KEY = "ああくないつTRPGはいたふと" HELP_MESSAGE = <<~TEXT - ■ 判定 (nADm>=x) - nDmのダイスロールをして、x 以下であれば成功。 - 出目が91以上でエラー。 - 出目が10以下でクリティカル。 + ■ 能力値判定 (nADm<=x) + nDmのダイスロールをして、出目が x 以下であれば成功。 + 失敗のうち、出目が91以上でエラー。 + 成功のうち、出目が10以下でクリティカル。 - ■ 判定 (nABm>=x) + ■ 攻撃/防御判定 (nABm<=x) nBmのダイスロールをして、 - x 以下であれば成功数+1。 - 出目が91以上でエラー。成功数+1。 - 出目が10以下でクリティカル。成功数-1。 + 出目が x 以下であれば成功数+1。 + 出目が x より上かつ91以上でエラー。成功数-1。 + 出目が x 以下かつ10以下でクリティカル。成功数さらに+1。 上記による成功数をカウント。 - ■ 判定 (nABm>=x--役職) + ■ 役職効果付き攻撃判定 (nABm<=x--役職名) nBmのダイスロールをして、 出目が x 以下であれば成功数+1。 - 出目が91以上でエラー。成功数+1。 - 出目が10以下でクリティカル。成功数-1。 - 上記による成功数をカウントした上で、以下の役職による成功数増加効果を適応。 - 狙撃(SNIPER) 成功数1以上のとき、成功数+1。 + 出目が x より上かつ91以上でエラー。成功数-1。 + 出目が x 以下かつ10以下でクリティカル。成功数さらに+1。 + 上記による成功数をカウントした上で、以下の役職名による成功数増加効果を適応。 + 狙撃(SNIPER): 成功数1以上のとき、成功数+1。 + + ■ 増悪判定(--WORSENING) + 症状を「末梢神経障害」「内臓機能不全」「精神症状」からランダムに選択。 + 継続ラウンド数を1d6+1で判定。 + + ■ 中毒判定(--ADDICTION) + 症状を「中枢神経障害」「多臓器不全」「急性ストレス反応」からランダムに選択。 + + ■ 判定の省略表記 + nADm、nABm、nABmにおいて、 + n(ダイス個数)を省略した場合、1として扱われる。 + m(ダイス種類)を省略した場合、100として扱われる。 + 例えば、AD<=90は1AD100<=90として解釈される。 TEXT register_prefix('\d*AD\d*', '\d*AB\d*', '--ADDICTION', '--WORSENING') @@ -42,6 +55,51 @@ def eval_game_system_specific_command(command) private + module Status + CRITICAL = 1 + SUCCESS = 2 + FAILURE = 3 + ERROR = 4 + end + + STATUS_NAME = { + Status::CRITICAL => 'クリティカル!', + Status::SUCCESS => '成功', + Status::FAILURE => '失敗', + Status::ERROR => 'エラー' + }.freeze + + # クリティカル、エラー、成功失敗周りの閾値や優先関係が複雑かつルールが変動する可能性があるため、明示的にルール管理するための関数。 + def check_roll(roll_result, target) + success = roll_result <= target + + crierror = + if roll_result <= 10 + "Critical" + elsif roll_result >= 91 + "Error" + else + "Neutral" + end + + result = + if success && (crierror == "Critical") + Status::CRITICAL + elsif success && (crierror == "Neutral") + Status::SUCCESS + elsif success && (crierror == "Error") + Status::SUCCESS + elsif !success && (crierror == "Critical") + Status::FAILURE + elsif !success && (crierror == "Neutral") + Status::FAILURE + elsif !success && (crierror == "Error") + Status::ERROR + end + + return result + end + def roll_ad(command) m = /^(\d*)AD(\d*)<=(\d+)$/.match(command) return nil unless m @@ -55,18 +113,19 @@ def roll_ad(command) end def roll_ab(command) - m = /^(\d*)AB(\d*)<=(\d+)(?:--([^\d\s]+)(0)?)?$/.match(command) + m = /^(\d*)AB(\d*)<=(\d+)(?:--([^\d\s]+)(0|1)?)?$/.match(command) return nil unless m times = m[1] sides = m[2] target = m[3].to_i type = m[4] - suffix = m[5] + type_enable = m[5] times = !times.empty? ? times.to_i : 1 sides = !sides.empty? ? sides.to_i : 100 + type_enable = !type_enable.nil? ? type_enable.to_i : 1 - if suffix || type.nil? + if type.nil? || (type_enable == 0) roll_b(command, times, sides, target) else roll_b_withtype(command, times, sides, target, type) @@ -76,31 +135,9 @@ def roll_ab(command) def roll_d(command, times, sides, target) dice_list = @randomizer.roll_barabara(times, sides).sort total = dice_list.sum - success = total <= target - crierror = - if total <= 10 - "Critical" - elsif total >= 91 - "Error" - else - "Neutral" - end - - result = - if success && (crierror == "Critical") - "クリティカル!" - elsif success && (crierror == "Neutral") - "成功" - elsif success && (crierror == "Error") - "成功" - elsif !success && (crierror == "Critical") - "失敗" - elsif !success && (crierror == "Neutral") - "失敗" - elsif !success && (crierror == "Error") - "エラー" - end + result = check_roll(total, target) + result = STATUS_NAME[result] if times == 1 return "(#{command}) > #{dice_list.join(',')} > #{result}" @@ -139,9 +176,17 @@ def process_b(times, sides, target) error_count = 0 dice_list.each do |value| - success_count += 1 if value <= target - critical_count += 1 if value <= 10 - error_count += 1 if value >= 91 + case check_roll(value, target) + when Status::CRITICAL + critical_count += 1 + success_count += 1 + when Status::SUCCESS + success_count += 1 + when Status::FAILURE + # Nothing to do + when Status::ERROR + error_count += 1 + end end return [dice_list, success_count, critical_count, error_count] diff --git a/test/data/ArknightsFan.toml b/test/data/ArknightsFan.toml index 2d09d9980..007189a7b 100644 --- a/test/data/ArknightsFan.toml +++ b/test/data/ArknightsFan.toml @@ -54,6 +54,14 @@ rands = [ { sides = 100, value = 95 }, ] +[[ test ]] +game_system = "ArknightsFan" +input = "AD<=5" +output = "(AD<=5) > 9 > 失敗" +rands = [ + { sides = 100, value = 9 }, +] + [[ test ]] game_system = "ArknightsFan" input = "AB<=70" @@ -146,6 +154,36 @@ rands = [ { sides = 100, value = 10 }, ] +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=5" +output = "(3AB100<=5) > [9,10,11] > 0+0C-0E > 成功数0" +rands = [ + { sides = 100, value = 9 }, + { sides = 100, value = 10 }, + { sides = 100, value = 11 }, +] + +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=5" +output = "(3AB100<=5) > [5,10,11] > 1+1C-0E > 成功数2" +rands = [ + { sides = 100, value = 5 }, + { sides = 100, value = 10 }, + { sides = 100, value = 11 }, +] + +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=95" +output = "(3AB100<=95) > [90,95,96] > 2+0C-1E > 成功数1" +rands = [ + { sides = 100, value = 90 }, + { sides = 100, value = 95 }, + { sides = 100, value = 96 }, +] + [[ test ]] game_system = "ArknightsFan" input = "4AB100<=60" @@ -360,6 +398,16 @@ rands = [ { sides = 100, value = 50 }, ] +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=70--Sniper1" +output = "(3AB100<=70--SNIPER1) > [50,50,90] > 2+0C-0E+1(SNIPER) > 成功数3" +rands = [ + { sides = 100, value = 90 }, + { sides = 100, value = 50 }, + { sides = 100, value = 50 }, +] + [[ test ]] game_system = "ArknightsFan" input = "3AB100<=70--先鋒" @@ -370,6 +418,26 @@ rands = [ { sides = 100, value = 50 }, ] +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=70--先鋒1" +output = "(3AB100<=70--先鋒1) > [50,50,90] > 2+0C-0E+0(先鋒) > 成功数2" +rands = [ + { sides = 100, value = 90 }, + { sides = 100, value = 50 }, + { sides = 100, value = 50 }, +] + +[[ test ]] +game_system = "ArknightsFan" +input = "3AB100<=70--先鋒0" +output = "(3AB100<=70--先鋒0) > [50,50,90] > 2+0C-0E > 成功数2" +rands = [ + { sides = 100, value = 90 }, + { sides = 100, value = 50 }, + { sides = 100, value = 50 }, +] + [[ test ]] game_system = "ArknightsFan" input = "--WORSENING"