diff --git a/lib/bcdice/game_system.rb b/lib/bcdice/game_system.rb index 539c18ded..5ed5a7e51 100644 --- a/lib/bcdice/game_system.rb +++ b/lib/bcdice/game_system.rb @@ -160,6 +160,7 @@ require "bcdice/game_system/NinjaSlayer2" require "bcdice/game_system/NjslyrBattle" require "bcdice/game_system/NobunagasBlackCastle" +require "bcdice/game_system/NRR" require "bcdice/game_system/NSSQ" require "bcdice/game_system/Nuekagami" require "bcdice/game_system/OneWayHeroics" diff --git a/lib/bcdice/game_system/NRR.rb b/lib/bcdice/game_system/NRR.rb new file mode 100644 index 000000000..08243161f --- /dev/null +++ b/lib/bcdice/game_system/NRR.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module BCDice + module GameSystem + class NRR < Base + # ゲームシステムの識別子 + ID = 'NRR' + + # ゲームシステム名 + NAME = 'nRR' + + # ゲームシステム名の読みがな + SORT_KEY = 'えぬああるあある' + + # ダイスボットの使い方 + HELP_MESSAGE = <<~INFO_MESSAGETEXT + ▪️判定 + ・ノーマルダイス NR8 + ・有利ダイス NR10 + ・不利ダイス NR6 + ・Exダイス NR12 + + ダイスの個数を指定しての判定ができます。 + 例:有利ダイス2個で判定 2NR10 + + ▪️判定結果とシンボル + ⭕:成功 + ❌:失敗 + ✨:クリティカル(大成功) + 💀:ファンブル(大失敗) + 🌈:ミラクル(奇跡) + INFO_MESSAGETEXT + + register_prefix('\d*NR(6|8|10|12)') + + def initialize(command) + super(command) + + @sort_barabara_dice = true # バラバラロール(Bコマンド)でソート有 + end + + def eval_game_system_specific_command(command) + roll_nr(command) + end + + private + + def roll_nr(command) + m = /^(\d+)?NR(6|8|10|12)$/.match(command) + return nil unless m + + times = m[1]&.to_i || 1 + table = case m[2] + when "6" + DISADVANTAGE + when "8" + NORMAL + when "10" + ADVANTAGE + else + EXTRA + end + + values = @randomizer.roll_barabara(times, table.size) + result = Result.new + text = + if times == 1 + level = table[values[0] - 1] + result.condition = SUCCESSES.include?(level) + result.fumble = level == :fumble + result.critical = CRITICALS.include?(level) + + "#{ICON[level]} #{RESULT_LABEL[level]}" + else + levels = values.map { |v| table[v - 1] } + values_count = levels + .group_by(&:itself) + .transform_values(&:length) + + values_count_strs = LEVELS.map do |l| + count = values_count.fetch(l, 0) + next nil if count == 0 + + "#{ICON[l]} #{count}" + end + + values_count_strs.compact.join(", ") + end + + times_str = times == 1 ? nil : times + result.text = "(#{times_str}NR#{m[2]}) > #{values.join(',')} > #{text}" + + result + end + + LEVELS = [:fumble, :failure, :success, :critical, :miracle].freeze + SUCCESSES = [:success, :critical, :miracle].freeze + CRITICALS = [:critical, :miracle].freeze + + DISADVANTAGE = [:fumble, :fumble, :failure, :failure, :success, :success].freeze + NORMAL = [:fumble, :failure, :failure, :failure, :success, :success, :success, :critical].freeze + ADVANTAGE = [:fumble, :failure, :failure, :success, :success, :success, :success, :success, :critical, :critical].freeze + EXTRA = [:fumble, :fumble, :fumble, :failure, :success, :success, :critical, :critical, :critical, :critical, :miracle, :miracle].freeze + + ICON = { + fumble: "💀", + failure: "❌", + success: "⭕️", + critical: "✨", + miracle: "🌈", + }.freeze + + RESULT_LABEL = { + fumble: "ファンブル(大失敗)", + failure: "失敗", + success: "成功", + critical: "クリティカル(大成功)", + miracle: "ミラクル(奇跡)", + }.freeze + end + end +end diff --git a/test/data/NRR.toml b/test/data/NRR.toml new file mode 100644 index 000000000..6f4a3895c --- /dev/null +++ b/test/data/NRR.toml @@ -0,0 +1,119 @@ +[[ test ]] +game_system = "NRR" +input = "NR6" +output = "(NR6) > 1 > 💀 ファンブル(大失敗)" +fumble = true +failure = true +rands = [ + { sides = 6, value = 1 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR6" +output = "(NR6) > 6 > ⭕️ 成功" +success = true +rands = [ + { sides = 6, value = 6 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR8" +output = "(NR8) > 1 > 💀 ファンブル(大失敗)" +fumble = true +failure = true +rands = [ + { sides = 8, value = 1 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR8" +output = "(NR8) > 8 > ✨ クリティカル(大成功)" +critical = true +success = true +rands = [ + { sides = 8, value = 8 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR10" +output = "(NR10) > 1 > 💀 ファンブル(大失敗)" +fumble = true +failure = true +rands = [ + { sides = 10, value = 1 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR10" +output = "(NR10) > 10 > ✨ クリティカル(大成功)" +critical = true +success = true +rands = [ + { sides = 10, value = 10 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR12" +output = "(NR12) > 1 > 💀 ファンブル(大失敗)" +fumble = true +failure = true +rands = [ + { sides = 12, value = 1 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR12" +output = "(NR12) > 4 > ❌ 失敗" +failure = true +rands = [ + { sides = 12, value = 4 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR12" +output = "(NR12) > 6 > ⭕️ 成功" +success = true +rands = [ + { sides = 12, value = 6 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR12" +output = "(NR12) > 10 > ✨ クリティカル(大成功)" +critical = true +success = true +rands = [ + { sides = 12, value = 10 }, +] + +[[ test ]] +game_system = "NRR" +input = "NR12" +output = "(NR12) > 12 > 🌈 ミラクル(奇跡)" +critical = true +success = true +rands = [ + { sides = 12, value = 12 }, +] + +[[ test ]] +game_system = "NRR" +input = "6NR12" +output = "(6NR12) > 3,4,5,7,11,12 > 💀 1, ❌ 1, ⭕️ 1, ✨ 1, 🌈 2" +rands = [ + { sides = 12, value = 3 }, + { sides = 12, value = 4 }, + { sides = 12, value = 5 }, + { sides = 12, value = 7 }, + { sides = 12, value = 11 }, + { sides = 12, value = 12 }, +]