diff --git a/lib/bcdice/game_system/Cthulhu7th.rb b/lib/bcdice/game_system/Cthulhu7th.rb index d8a10af22..ea4a0b637 100644 --- a/lib/bcdice/game_system/Cthulhu7th.rb +++ b/lib/bcdice/game_system/Cthulhu7th.rb @@ -47,18 +47,14 @@ class Cthulhu7th < Base register_prefix('CC\(\d+\)', 'CC.*', 'CBR\(\d+,\d+\)', 'FAR.*', 'BMR', 'BMS', 'FCL', 'FCM', 'PH', 'MA') - def initialize(command) - super(command) - - @bonus_dice_range = (-2..2) - end + BONUS_DICE_RANGE = (-2..2).freeze def eval_game_system_specific_command(command) case command when /^CC/i - return getCheckResult(command) + return skill_roll(command) when /^CBR/i - return getCombineRoll(command) + return combine_roll(command) when /^FAR/i return getFullAutoResult(command) when /^BMR/i # 狂気の発作(リアルタイム) @@ -80,6 +76,52 @@ def eval_game_system_specific_command(command) private + class ResultLevel + LEVEL = [ + :fumble, + :failure, + :regular_success, + :hard_success, + :extreme_success, + :critical, + ].freeze + + LEVEL_TO_S = { + critical: "クリティカル", + extreme_success: "イクストリーム成功", + hard_success: "ハード成功", + regular_success: "レギュラー成功", + fumble: "ファンブル", + failure: "失敗", + }.freeze + + def initialize(level) + @level = level + @level_index = LEVEL.index(level) + raise ArgumentError unless @level_index + end + + def success? + @level_index >= LEVEL.index(:regular_success) + end + + def failure? + @level_index <= LEVEL.index(:failure) + end + + def critical? + @level == :critical + end + + def fumble? + @level == :fumble + end + + def to_s + LEVEL_TO_S[@level] + end + end + def roll_1d8_table(table_name, table) total_n = @randomizer.roll_once(8) index = total_n - 1 @@ -98,37 +140,44 @@ def roll_1d100_table(table_name, table) return "#{table_name}(#{total_n}) > #{text}" end - def getCheckResult(command) - m = /^CC([-+]?\d+)?(<=(\d+))?/i.match(command) + def skill_roll(command) + m = /^CC([-+]?\d+)?(?:<=(\d+))?$/.match(command) unless m return nil end - bonus_dice_count = m[1].to_i # ボーナス・ペナルティダイスの個数 - diff = m[3].to_i - without_compare = m[2].nil? || diff <= 0 + bonus_dice = m[1].to_i + difficulty = m[2].to_i - if bonus_dice_count == 0 && diff <= 0 + if bonus_dice == 0 && difficulty == 0 dice = @randomizer.roll_once(100) return "1D100 > #{dice}" end - unless @bonus_dice_range.include?(bonus_dice_count) - return "エラー。ボーナス・ペナルティダイスの値は#{@bonus_dice_range.min}~#{@bonus_dice_range.max}です。" + unless BONUS_DICE_RANGE.include?(bonus_dice) + return "エラー。ボーナス・ペナルティダイスの値は#{BONUS_DICE_RANGE.min}~#{BONUS_DICE_RANGE.max}です。" end - total, total_list = roll_with_bonus(bonus_dice_count) + total, total_list = roll_with_bonus(bonus_dice) - if without_compare - output = "(1D100) ボーナス・ペナルティダイス[#{bonus_dice_count}]" - output += " > #{total_list.join(', ')} > #{total}" - else - result_text = getCheckResultText(total, diff) - output = "(1D100<=#{diff}) ボーナス・ペナルティダイス[#{bonus_dice_count}]" - output += " > #{total_list.join(', ')} > #{total} > #{result_text}" - end + expr = difficulty.zero? ? "1D100" : "1D100<=#{difficulty}" + result = result_level(total, difficulty) unless difficulty.zero? - return output + sequence = [ + "(#{expr}) ボーナス・ペナルティダイス[#{bonus_dice}]", + total_list.join(", "), + total, + result, + ].compact + + Result.new.tap do |r| + r.text = sequence.join(" > ") + if result + r.condition = result.success? + r.critical = result.critical? + r.fumble = result.fumble? + end + end end # 1D100の一の位用のダイスロール @@ -163,58 +212,50 @@ def roll_with_bonus(bonus) return dice, dice_list end - def getCheckResultText(total, diff, fumbleable = false) - if total <= diff - return "クリティカル" if total == 1 - return "イクストリーム成功" if total <= (diff / 5) - return "ハード成功" if total <= (diff / 2) - - return "レギュラー成功" - end - - fumble_text = "ファンブル" - - return fumble_text if total == 100 - - if total >= 96 - if diff < 50 - return fumble_text - else - return fumble_text if fumbleable - end + def result_level(total, difficulty, fumbleable = false) + fumble = difficulty < 50 || fumbleable ? 96 : 100 + + if total == 1 + ResultLevel.new(:critical) + elsif total <= (difficulty / 5) + ResultLevel.new(:extreme_success) + elsif total <= (difficulty / 2) + ResultLevel.new(:hard_success) + elsif total <= difficulty + ResultLevel.new(:regular_success) + elsif total >= fumble + ResultLevel.new(:fumble) + else + ResultLevel.new(:failure) end - - return "失敗" end - def getCombineRoll(command) - return nil unless /CBR\((\d+),(\d+)\)/i =~ command + def combine_roll(command) + m = /^CBR\((\d+),(\d+)\)$/.match(command) + return nil unless m - diff_1 = Regexp.last_match(1).to_i - diff_2 = Regexp.last_match(2).to_i + difficulty_1 = m[1].to_i + difficulty_2 = m[2].to_i total = @randomizer.roll_once(100) - result_1 = getCheckResultText(total, diff_1) - result_2 = getCheckResultText(total, diff_2) - - successList = ["クリティカル", "イクストリーム成功", "ハード成功", "レギュラー成功"] - - succesCount = 0 - succesCount += 1 if successList.include?(result_1) - succesCount += 1 if successList.include?(result_2) - debug("succesCount", succesCount) + result_1 = result_level(total, difficulty_1) + result_2 = result_level(total, difficulty_2) rank = - if succesCount >= 2 + if result_1.success? && result_2.success? "成功" - elsif succesCount == 1 + elsif result_1.success? || result_2.success? "部分的成功" else "失敗" end - return "(1d100<=#{diff_1},#{diff_2}) > #{total}[#{result_1},#{result_2}] > #{rank}" + Result.new.tap do |r| + r.text = "(1d100<=#{difficulty_1},#{difficulty_2}) > #{total}[#{result_1},#{result_2}] > #{rank}" + r.success = result_1.success? && result_2.success? + r.failure = result_1.failure? && result_2.failure? + end end def getFullAutoResult(command) @@ -261,8 +302,8 @@ def getFullAutoResult(command) broken_number = broken_number.abs end - unless @bonus_dice_range.include?(bonus_dice_count) - return "エラー。ボーナス・ペナルティダイスの値は#{@bonus_dice_range.min}~#{@bonus_dice_range.max}です。" + unless BONUS_DICE_RANGE.include?(bonus_dice_count) + return "エラー。ボーナス・ペナルティダイスの値は#{BONUS_DICE_RANGE.min}~#{BONUS_DICE_RANGE.max}です。" end output += "ボーナス・ペナルティダイス[#{bonus_dice_count}]" @@ -286,7 +327,7 @@ def rollFullAuto(bullet_count, diff, broken_number, dice_num, stop_count, bullet output += getNextDifficultyMessage(more_difficulty) # ペナルティダイスを減らしながらロール用ループ - while dice_num >= @bonus_dice_range.min + while dice_num >= BONUS_DICE_RANGE.min loopCount += 1 hit_result, total, total_list = getHitResultInfos(dice_num, diff, more_difficulty) @@ -349,7 +390,7 @@ def getHitResultInfos(dice_num, diff, more_difficulty) total, total_list = roll_with_bonus(dice_num) fumbleable = getFumbleable(more_difficulty) - hit_result = getCheckResultText(total, diff, fumbleable) + hit_result = result_level(total, diff, fumbleable).to_s return hit_result, total, total_list end diff --git a/lib/bcdice/game_system/PulpCthulhu.rb b/lib/bcdice/game_system/PulpCthulhu.rb index ac4f0ca55..e5ef2e048 100644 --- a/lib/bcdice/game_system/PulpCthulhu.rb +++ b/lib/bcdice/game_system/PulpCthulhu.rb @@ -52,9 +52,9 @@ class PulpCthulhu < Cthulhu7th def eval_game_system_specific_command(command) case command when /^CC/i - return getCheckResult(command) + return skill_roll(command) when /^CBR/i - return getCombineRoll(command) + return combine_roll(command) when /^FAR/i return getFullAutoResult(command) when /^BMR/i # 狂気の発作(リアルタイム) diff --git a/test/data/Cthulhu7th.toml b/test/data/Cthulhu7th.toml index 506e6d6f2..de1104199 100644 --- a/test/data/Cthulhu7th.toml +++ b/test/data/Cthulhu7th.toml @@ -2,6 +2,7 @@ game_system = "Cthulhu7th" input = "CBR(70,30)" output = "(1d100<=70,30) > 30[ハード成功,レギュラー成功] > 成功" +success = true rands = [ { sides = 100, value = 30 }, ] @@ -26,6 +27,7 @@ rands = [ game_system = "Cthulhu7th" input = "CBR(70,69)" output = "(1d100<=70,69) > 14[イクストリーム成功,ハード成功] > 成功" +success = true rands = [ { sides = 100, value = 14 }, ] @@ -34,6 +36,7 @@ rands = [ game_system = "Cthulhu7th" input = "CBR(70,30)" output = "(1d100<=70,30) > 100[ファンブル,ファンブル] > 失敗" +failure = true rands = [ { sides = 100, value = 100 }, ] @@ -42,6 +45,7 @@ rands = [ game_system = "Cthulhu7th" input = "CBR(70,30)" output = "(1d100<=70,30) > 1[クリティカル,クリティカル] > 成功" +success = true rands = [ { sides = 100, value = 1 }, ] @@ -50,6 +54,7 @@ rands = [ game_system = "Cthulhu7th" input = "CBR(25,20)" output = "(1d100<=25,20) > 1[クリティカル,クリティカル] > 成功" +success = true rands = [ { sides = 100, value = 1 }, ] @@ -66,6 +71,7 @@ rands = [ game_system = "Cthulhu7th" input = "CBR(90,40)" output = "(1d100<=90,40) > 97[失敗,ファンブル] > 失敗" +failure = true rands = [ { sides = 100, value = 97 }, ] @@ -88,6 +94,7 @@ rands = [] game_system = "Cthulhu7th" input = "CC(-1)<=93" output = "(1D100<=93) ボーナス・ペナルティダイス[-1] > 92, 72 > 92 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 7 }, @@ -98,6 +105,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(1)<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[1] > 92, 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 }, @@ -108,6 +116,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(+1)<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[1] > 92, 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 }, @@ -118,6 +127,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(1)<=46" output = "(1D100<=46) ボーナス・ペナルティダイス[1] > 47, 37 > 37 > レギュラー成功" +success = true rands = [ { sides = 10, value = 4 }, { sides = 10, value = 3 }, @@ -128,6 +138,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-1)<=46" output = "(1D100<=46) ボーナス・ペナルティダイス[-1] > 47, 37 > 47 > 失敗" +failure = true rands = [ { sides = 10, value = 4 }, { sides = 10, value = 3 }, @@ -138,6 +149,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(1)<=63" output = "(1D100<=63) ボーナス・ペナルティダイス[1] > 100, 100 > 100 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 10 }, @@ -148,6 +161,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-1)<=63" output = "(1D100<=63) ボーナス・ペナルティダイス[-1] > 100, 100 > 100 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 10 }, @@ -158,6 +173,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(1)<=63" output = "(1D100<=63) ボーナス・ペナルティダイス[1] > 1, 1 > 1 > クリティカル" +success = true +critical = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 10 }, @@ -168,6 +185,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-1)<=63" output = "(1D100<=63) ボーナス・ペナルティダイス[-1] > 1, 1 > 1 > クリティカル" +success = true +critical = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 10 }, @@ -178,6 +197,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(0)<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[0] > 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 5 }, { sides = 10, value = 2 }, @@ -187,6 +207,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[0] > 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 5 }, { sides = 10, value = 2 }, @@ -196,6 +217,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=5" output = "(1D100<=5) ボーナス・ペナルティダイス[0] > 2 > 2 > ハード成功" +success = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 2 }, @@ -205,6 +227,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(2)<=73" output = "(1D100<=73) ボーナス・ペナルティダイス[2] > 24, 14, 54 > 14 > イクストリーム成功" +success = true rands = [ { sides = 10, value = 2 }, { sides = 10, value = 1 }, @@ -216,6 +239,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(2)<=73" output = "(1D100<=73) ボーナス・ペナルティダイス[2] > 20, 100, 50 > 20 > ハード成功" +success = true rands = [ { sides = 10, value = 2 }, { sides = 10, value = 10 }, @@ -227,6 +251,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-2)<=43" output = "(1D100<=43) ボーナス・ペナルティダイス[-2] > 97, 67, 37 > 97 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 6 }, @@ -238,6 +264,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-2)<=80" output = "(1D100<=80) ボーナス・ペナルティダイス[-2] > 100, 60, 50 > 100 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 6 }, @@ -249,6 +277,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC(-1)<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[-1] > 97, 67 > 97 > 失敗" +failure = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 6 }, @@ -259,6 +288,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=49" output = "(1D100<=49) ボーナス・ペナルティダイス[0] > 95 > 95 > 失敗" +failure = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 }, @@ -268,6 +298,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=49" output = "(1D100<=49) ボーナス・ペナルティダイス[0] > 96 > 96 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 6 }, @@ -277,6 +309,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=50" output = "(1D100<=50) ボーナス・ペナルティダイス[0] > 99 > 99 > 失敗" +failure = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 9 }, @@ -286,6 +319,8 @@ rands = [ game_system = "Cthulhu7th" input = "CC<=50" output = "(1D100<=50) ボーナス・ペナルティダイス[0] > 100 > 100 > ファンブル" +failure = true +fumble = true rands = [ { sides = 10, value = 10 }, { sides = 10, value = 10 }, @@ -348,6 +383,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC-1<=93 ペナルティダイス指定カッコなし" output = "(1D100<=93) ボーナス・ペナルティダイス[-1] > 92, 72 > 92 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 7 }, @@ -358,6 +394,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC1<=53 ボーナスダイス指定カッコなし" output = "(1D100<=53) ボーナス・ペナルティダイス[1] > 92, 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 }, @@ -368,6 +405,7 @@ rands = [ game_system = "Cthulhu7th" input = "CC+1<=53 ボーナスダイス指定カッコなし" output = "(1D100<=53) ボーナス・ペナルティダイス[1] > 92, 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 }, diff --git a/test/data/PulpCthulhu.toml b/test/data/PulpCthulhu.toml index 10a258d5d..897e64bd9 100644 --- a/test/data/PulpCthulhu.toml +++ b/test/data/PulpCthulhu.toml @@ -152,6 +152,7 @@ rands = [ game_system = "PulpCthulhu" input = "CBR(70,30)" output = "(1d100<=70,30) > 30[ハード成功,レギュラー成功] > 成功" +success = true rands = [ { sides = 100, value = 30 }, ] @@ -160,6 +161,7 @@ rands = [ game_system = "PulpCthulhu" input = "CC(1)<=53" output = "(1D100<=53) ボーナス・ペナルティダイス[1] > 92, 52 > 52 > レギュラー成功" +success = true rands = [ { sides = 10, value = 9 }, { sides = 10, value = 5 },