bcdice 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/lib/bcdice/arithmetic/parser.rb +4 -2
- data/lib/bcdice/base.rb +1 -1
- data/lib/bcdice/command/parser.rb +4 -2
- data/lib/bcdice/common_command/add_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/barabara_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/calc/parser.rb +4 -2
- data/lib/bcdice/common_command/reroll_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/tally_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/upper_dice/parser.rb +4 -2
- data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
- data/lib/bcdice/game_system/Alsetto.rb +2 -2
- data/lib/bcdice/game_system/AniMalus.rb +221 -0
- data/lib/bcdice/game_system/ArknightsFan.rb +182 -0
- data/lib/bcdice/game_system/Avandner.rb +1 -1
- data/lib/bcdice/game_system/BBN.rb +1 -1
- data/lib/bcdice/game_system/BadLife.rb +3 -3
- data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
- data/lib/bcdice/game_system/Chill3.rb +6 -6
- data/lib/bcdice/game_system/DarkSouls.rb +1 -1
- data/lib/bcdice/game_system/Elric.rb +1 -1
- data/lib/bcdice/game_system/FullFace.rb +92 -0
- data/lib/bcdice/game_system/InfiniteFantasia.rb +4 -1
- data/lib/bcdice/game_system/Irisbane.rb +1 -1
- data/lib/bcdice/game_system/KillDeathBusiness.rb +1 -1
- data/lib/bcdice/game_system/KyokoShinshoku.rb +158 -0
- data/lib/bcdice/game_system/Liminal.rb +136 -0
- data/lib/bcdice/game_system/MetalHead.rb +1 -1
- data/lib/bcdice/game_system/MetalHeadExtream.rb +1 -1
- data/lib/bcdice/game_system/NRR.rb +122 -0
- data/lib/bcdice/game_system/NSSQ.rb +1 -1
- data/lib/bcdice/game_system/NightWizard.rb +1 -1
- data/lib/bcdice/game_system/NightWizard3rd.rb +15 -2
- data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
- data/lib/bcdice/game_system/PastFutureParadox.rb +1238 -0
- data/lib/bcdice/game_system/Postman.rb +3 -3
- data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
- data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +1 -1
- data/lib/bcdice/game_system/Ryutama.rb +4 -4
- data/lib/bcdice/game_system/Siren.rb +97 -0
- data/lib/bcdice/game_system/Skynauts.rb +1 -1
- data/lib/bcdice/game_system/Strave.rb +1 -1
- data/lib/bcdice/game_system/TherapieSein.rb +1 -1
- data/lib/bcdice/game_system/TrinitySeven.rb +1 -1
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +12 -6
- data/lib/bcdice/game_system/WerewolfTheApocalypse5th.rb +12 -6
- data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +1 -1
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +4 -2
- data/lib/bcdice/game_system.rb +8 -0
- data/lib/bcdice/loader.rb +1 -1
- data/lib/bcdice/version.rb +1 -1
- metadata +27 -5
| @@ -0,0 +1,136 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module BCDice
         | 
| 4 | 
            +
              module GameSystem
         | 
| 5 | 
            +
                class Liminal < Base
         | 
| 6 | 
            +
                  # ゲームシステムの識別子
         | 
| 7 | 
            +
                  ID = 'Liminal'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # ゲームシステム名
         | 
| 10 | 
            +
                  NAME = 'リミナル'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # ゲームシステム名の読みがな
         | 
| 13 | 
            +
                  SORT_KEY = 'りみなる'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # ダイスボットの使い方
         | 
| 16 | 
            +
                  HELP_MESSAGE = <<~INFO_MESSAGETEXT
         | 
| 17 | 
            +
                    ■技能判定 LMx+b>=t+m   x:技能レベル b:ボーナス t:難易度 m:敵の技能レベル(対抗判定)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    例)LM2>=8:  技能レベル2,難易度8で技能判定し、その結果を表示。(クリティカル成功も表示)
         | 
| 20 | 
            +
                       LM3+2>=9:技能レベル3,ボーナス+2,難易度9で技能判定し、その結果を表示。( 〃 )
         | 
| 21 | 
            +
                       LM0>=8:  技能なし,難易度8で技能判定する。(難易度+2は自動的に足されます)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    ■イニシアティヴ判定 LIx+b>=t+m   x:認識力レベル b:ボーナス t:難易度 m:敵の認識力レベル
         | 
| 24 | 
            +
                    例)LI2>=8+2:  認識力レベル2,難易度8,敵認識力レベル2で技能判定し、その結果を表示。
         | 
| 25 | 
            +
                       LI0>=8+2:  認識力なし,難易度8,敵認識力レベル2で技能判定する。(難易度加算なし)
         | 
| 26 | 
            +
                  INFO_MESSAGETEXT
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  register_prefix("LI", "LM")
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def eval_game_system_specific_command(command)
         | 
| 31 | 
            +
                    resolute_action(command) || resolute_initiative(command)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  private
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  # 技能判定
         | 
| 37 | 
            +
                  # @param [String] command
         | 
| 38 | 
            +
                  # @return [Result]
         | 
| 39 | 
            +
                  def resolute_action(command)
         | 
| 40 | 
            +
                    parser = Command::Parser.new("LM", round_type: @round_type)
         | 
| 41 | 
            +
                                            .has_suffix_number
         | 
| 42 | 
            +
                                            .restrict_cmp_op_to(:>=)
         | 
| 43 | 
            +
                    parsed = parser.parse(command)
         | 
| 44 | 
            +
                    return nil unless parsed
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    skill_level = parsed.suffix_number
         | 
| 47 | 
            +
                    bonus = parsed.modify_number
         | 
| 48 | 
            +
                    difficulty = parsed.target_number
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    dice = @randomizer.roll_barabara(2, 6)
         | 
| 51 | 
            +
                    dice_total = dice.sum
         | 
| 52 | 
            +
                    total = dice_total + skill_level + bonus
         | 
| 53 | 
            +
                    difficulty += 2 if skill_level == 0
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    return Result.new.tap do |result|
         | 
| 56 | 
            +
                      result.condition = (total >= difficulty)
         | 
| 57 | 
            +
                      result.critical = (total >= difficulty + 5)
         | 
| 58 | 
            +
                      if dice_total == 2
         | 
| 59 | 
            +
                        result.fumble = true
         | 
| 60 | 
            +
                        result.critical = false
         | 
| 61 | 
            +
                        result.condition = false
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      sequence = [
         | 
| 65 | 
            +
                        "(LM#{skill_level}#{with_symbol(bonus)}>=#{difficulty})",
         | 
| 66 | 
            +
                        "#{dice_total}[#{dice.join(',')}]#{with_symbol(skill_level + bonus)}",
         | 
| 67 | 
            +
                        total.to_s,
         | 
| 68 | 
            +
                        if result.fumble?
         | 
| 69 | 
            +
                          "1ゾロ"
         | 
| 70 | 
            +
                        elsif result.critical?
         | 
| 71 | 
            +
                          "クリティカル"
         | 
| 72 | 
            +
                        else
         | 
| 73 | 
            +
                          result.success? ? "成功" : "失敗"
         | 
| 74 | 
            +
                        end
         | 
| 75 | 
            +
                      ].compact
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                      result.text = sequence.join(" > ")
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  def with_symbol(number)
         | 
| 82 | 
            +
                    if number == 0
         | 
| 83 | 
            +
                      return "+0"
         | 
| 84 | 
            +
                    elsif number > 0
         | 
| 85 | 
            +
                      return "+#{number}"
         | 
| 86 | 
            +
                    else
         | 
| 87 | 
            +
                      return number.to_s
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  # イニシアティヴ判定
         | 
| 92 | 
            +
                  # @param [String] command
         | 
| 93 | 
            +
                  # @return [Result]
         | 
| 94 | 
            +
                  def resolute_initiative(command)
         | 
| 95 | 
            +
                    parser = Command::Parser.new("LI", round_type: @round_type)
         | 
| 96 | 
            +
                                            .has_suffix_number
         | 
| 97 | 
            +
                                            .restrict_cmp_op_to(:>=)
         | 
| 98 | 
            +
                    parsed = parser.parse(command)
         | 
| 99 | 
            +
                    return nil unless parsed
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    skill_level = parsed.suffix_number
         | 
| 102 | 
            +
                    bonus = parsed.modify_number
         | 
| 103 | 
            +
                    difficulty = parsed.target_number
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    dice = @randomizer.roll_barabara(2, 6)
         | 
| 106 | 
            +
                    dice_total = dice.sum
         | 
| 107 | 
            +
                    total = dice_total + skill_level + bonus
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    return Result.new.tap do |result|
         | 
| 110 | 
            +
                      result.condition = (total >= difficulty)
         | 
| 111 | 
            +
                      result.critical = (total >= difficulty + 5)
         | 
| 112 | 
            +
                      if dice_total == 2
         | 
| 113 | 
            +
                        result.fumble = true
         | 
| 114 | 
            +
                        result.critical = false
         | 
| 115 | 
            +
                        result.condition = false
         | 
| 116 | 
            +
                      end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                      sequence = [
         | 
| 119 | 
            +
                        "(LI#{skill_level}#{with_symbol(bonus)}>=#{difficulty})",
         | 
| 120 | 
            +
                        "#{dice_total}[#{dice.join(',')}]#{with_symbol(skill_level + bonus)}",
         | 
| 121 | 
            +
                        total.to_s,
         | 
| 122 | 
            +
                        if result.fumble?
         | 
| 123 | 
            +
                          "1ゾロ"
         | 
| 124 | 
            +
                        elsif result.critical?
         | 
| 125 | 
            +
                          "クリティカル"
         | 
| 126 | 
            +
                        else
         | 
| 127 | 
            +
                          result.success? ? "成功" : "失敗"
         | 
| 128 | 
            +
                        end
         | 
| 129 | 
            +
                      ].compact
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                      result.text = sequence.join(" > ")
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
            end
         | 
| @@ -151,7 +151,7 @@ module BCDice | |
| 151 151 | 
             
                      'D' => [{'LW' => 2}, {'MW' => 26}, {'HW' => 46}, {'MO' => 76}, {'K' => 96}],
         | 
| 152 152 | 
             
                      'E' => [{'LW' => 2}, {'MW' => 26}, {'HW' => 39}, {'MO' => 54}, {'K' => 76}],
         | 
| 153 153 | 
             
                      'F' => [{'LW' => 2}, {'MW' => 16}, {'HW' => 39}, {'MO' => 54}, {'K' => 66}],
         | 
| 154 | 
            -
                      'G' => [{'LW' => 2}, {'MW' => | 
| 154 | 
            +
                      'G' => [{'LW' => 2}, {'MW' => 6}, {'HW' => 16}, {'MO' => 26}, {'K' => 39}],
         | 
| 155 155 | 
             
                      'M' => [{'0'  => 2}, {'1' => 22}, {'2' => 42}, {'3' => 62}, {'4' => 82}, {'5' => 92}, {'6' => 102}, {'8' => 112}],
         | 
| 156 156 | 
             
                    }
         | 
| 157 157 |  | 
| @@ -0,0 +1,122 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module BCDice
         | 
| 4 | 
            +
              module GameSystem
         | 
| 5 | 
            +
                class NRR < Base
         | 
| 6 | 
            +
                  # ゲームシステムの識別子
         | 
| 7 | 
            +
                  ID = 'NRR'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # ゲームシステム名
         | 
| 10 | 
            +
                  NAME = 'nRR'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # ゲームシステム名の読みがな
         | 
| 13 | 
            +
                  SORT_KEY = 'えぬああるあある'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # ダイスボットの使い方
         | 
| 16 | 
            +
                  HELP_MESSAGE = <<~INFO_MESSAGETEXT
         | 
| 17 | 
            +
                    ▪️判定
         | 
| 18 | 
            +
                    ・ノーマルダイス NR8
         | 
| 19 | 
            +
                    ・有利ダイス NR10
         | 
| 20 | 
            +
                    ・不利ダイス NR6
         | 
| 21 | 
            +
                    ・Exダイス NR12
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    ダイスの個数を指定しての判定ができます。
         | 
| 24 | 
            +
                    例:有利ダイス2個で判定 2NR10
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    ▪️判定結果とシンボル
         | 
| 27 | 
            +
                    ⭕:成功
         | 
| 28 | 
            +
                    ❌:失敗
         | 
| 29 | 
            +
                    ✨:クリティカル(大成功)
         | 
| 30 | 
            +
                    💀:ファンブル(大失敗)
         | 
| 31 | 
            +
                    🌈:ミラクル(奇跡)
         | 
| 32 | 
            +
                  INFO_MESSAGETEXT
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  register_prefix('\d*NR(6|8|10|12)')
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def initialize(command)
         | 
| 37 | 
            +
                    super(command)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    @sort_barabara_dice = true # バラバラロール(Bコマンド)でソート有
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def eval_game_system_specific_command(command)
         | 
| 43 | 
            +
                    roll_nr(command)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  private
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def roll_nr(command)
         | 
| 49 | 
            +
                    m = /^(\d+)?NR(6|8|10|12)$/.match(command)
         | 
| 50 | 
            +
                    return nil unless m
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    times = m[1]&.to_i || 1
         | 
| 53 | 
            +
                    table = case m[2]
         | 
| 54 | 
            +
                            when "6"
         | 
| 55 | 
            +
                              DISADVANTAGE
         | 
| 56 | 
            +
                            when "8"
         | 
| 57 | 
            +
                              NORMAL
         | 
| 58 | 
            +
                            when "10"
         | 
| 59 | 
            +
                              ADVANTAGE
         | 
| 60 | 
            +
                            else
         | 
| 61 | 
            +
                              EXTRA
         | 
| 62 | 
            +
                            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    values = @randomizer.roll_barabara(times, table.size)
         | 
| 65 | 
            +
                    result = Result.new
         | 
| 66 | 
            +
                    text =
         | 
| 67 | 
            +
                      if times == 1
         | 
| 68 | 
            +
                        level = table[values[0] - 1]
         | 
| 69 | 
            +
                        result.condition = SUCCESSES.include?(level)
         | 
| 70 | 
            +
                        result.fumble = level == :fumble
         | 
| 71 | 
            +
                        result.critical = CRITICALS.include?(level)
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                        "#{ICON[level]} #{RESULT_LABEL[level]}"
         | 
| 74 | 
            +
                      else
         | 
| 75 | 
            +
                        levels = values.map { |v| table[v - 1] }
         | 
| 76 | 
            +
                        values_count = levels
         | 
| 77 | 
            +
                                       .group_by(&:itself)
         | 
| 78 | 
            +
                                       .transform_values(&:length)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                        values_count_strs = LEVELS.map do |l|
         | 
| 81 | 
            +
                          count = values_count.fetch(l, 0)
         | 
| 82 | 
            +
                          next nil if count == 0
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                          "#{ICON[l]} #{count}"
         | 
| 85 | 
            +
                        end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                        values_count_strs.compact.join(", ")
         | 
| 88 | 
            +
                      end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    times_str = times == 1 ? nil : times
         | 
| 91 | 
            +
                    result.text = "(#{times_str}NR#{m[2]}) > #{values.join(',')} > #{text}"
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    result
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  LEVELS = [:fumble, :failure, :success, :critical, :miracle].freeze
         | 
| 97 | 
            +
                  SUCCESSES = [:success, :critical, :miracle].freeze
         | 
| 98 | 
            +
                  CRITICALS = [:critical, :miracle].freeze
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  DISADVANTAGE = [:fumble, :fumble, :failure, :failure, :success, :success].freeze
         | 
| 101 | 
            +
                  NORMAL = [:fumble, :failure, :failure, :failure, :success, :success, :success, :critical].freeze
         | 
| 102 | 
            +
                  ADVANTAGE = [:fumble, :failure, :failure, :success, :success, :success, :success, :success, :critical, :critical].freeze
         | 
| 103 | 
            +
                  EXTRA = [:fumble, :fumble, :fumble, :failure, :success, :success, :critical, :critical, :critical, :critical, :miracle, :miracle].freeze
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  ICON = {
         | 
| 106 | 
            +
                    fumble: "💀",
         | 
| 107 | 
            +
                    failure: "❌",
         | 
| 108 | 
            +
                    success: "⭕️",
         | 
| 109 | 
            +
                    critical: "✨",
         | 
| 110 | 
            +
                    miracle: "🌈",
         | 
| 111 | 
            +
                  }.freeze
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  RESULT_LABEL = {
         | 
| 114 | 
            +
                    fumble: "ファンブル(大失敗)",
         | 
| 115 | 
            +
                    failure: "失敗",
         | 
| 116 | 
            +
                    success: "成功",
         | 
| 117 | 
            +
                    critical: "クリティカル(大成功)",
         | 
| 118 | 
            +
                    miracle: "ミラクル(奇跡)",
         | 
| 119 | 
            +
                  }.freeze
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
            end
         | 
| @@ -123,7 +123,7 @@ module BCDice | |
| 123 123 |  | 
| 124 124 | 
             
                  # @return [ParsedNW, nil]
         | 
| 125 125 | 
             
                  def parse_nw(string)
         | 
| 126 | 
            -
                    m = /^([-+]?\d+)?#{@nw_command}((?:[-+]\d+)+)?(?:@(\d+(?:,\d+)*))?(?:#(\d+(?:,\d+)*))?(?:\$(\d+ | 
| 126 | 
            +
                    m = /^([-+]?\d+)?#{@nw_command}((?:[-+]\d+)+)?(?:@(\d+(?:,\d+)*))?(?:#(\d+(?:,\d+)*))?(?:\$(\d+))?((?:[-+]\d+)+)?(?:([>=]+)(\d+))?$/.match(string)
         | 
| 127 127 | 
             
                    unless m
         | 
| 128 128 | 
             
                      return nil
         | 
| 129 129 | 
             
                    end
         | 
| @@ -5,14 +5,27 @@ require 'bcdice/game_system/NightWizard' | |
| 5 5 | 
             
            module BCDice
         | 
| 6 6 | 
             
              module GameSystem
         | 
| 7 7 | 
             
                class NightWizard3rd < NightWizard
         | 
| 8 | 
            +
                  # ゲームシステムの識別子
         | 
| 9 | 
            +
                  ID = 'NightWizard3rd'
         | 
| 10 | 
            +
             | 
| 8 11 | 
             
                  # ゲームシステム名
         | 
| 9 12 | 
             
                  NAME = 'ナイトウィザード The 3rd Edition'
         | 
| 10 13 |  | 
| 11 14 | 
             
                  # ゲームシステム名の読みがな
         | 
| 12 15 | 
             
                  SORT_KEY = 'ないとういさあと3'
         | 
| 13 16 |  | 
| 14 | 
            -
                  #  | 
| 15 | 
            -
                   | 
| 17 | 
            +
                  # ダイスボットの使い方
         | 
| 18 | 
            +
                  HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
         | 
| 19 | 
            +
                    ・判定用コマンド (aNW+b@x#y$z+c)
         | 
| 20 | 
            +
                      a : 基本値
         | 
| 21 | 
            +
                      b : 常時に準じる特技による補正
         | 
| 22 | 
            +
                      c : 常時以外の特技、および支援効果による補正
         | 
| 23 | 
            +
                      x : クリティカル値のカンマ区切り(省略時 10)
         | 
| 24 | 
            +
                      y : ファンブル値のカンマ区切り(省略時 5)
         | 
| 25 | 
            +
                      z : プラーナによる達成値補正のプラーナ消費数(ファンブル時には適用されない)
         | 
| 26 | 
            +
                     クリティカル値、ファンブル値が無い場合は1や13などのあり得ない数値を入れてください。
         | 
| 27 | 
            +
                     例)12NW-5@7#2$3 1NW 50nw+5@7,10#2,5 50nw-5+10@7,10#2,5+15+25
         | 
| 28 | 
            +
                  INFO_MESSAGE_TEXT
         | 
| 16 29 |  | 
| 17 30 | 
             
                  register_prefix('([-+]?\d+)?NW', '2R6')
         | 
| 18 31 |  |