bcdice/BCDice

View on GitHub
lib/bcdice/game_system/ShinkuuGakuen.rb

Summary

Maintainability
F
4 days
Test Coverage
A
99%
# frozen_string_literal: true

module BCDice
  module GameSystem
    class ShinkuuGakuen < Base
      # ゲームシステムの識別子
      ID = 'ShinkuuGakuen'

      # ゲームシステム名
      NAME = '真空学園'

      # ゲームシステム名の読みがな
      SORT_KEY = 'しんくうかくえん'

      # ダイスボットの使い方
      HELP_MESSAGE = <<~MESSAGETEXT
        ・判定
        RLx:技能ベースxで技能チェックのダイスロール
        RLx>=y:この書式なら目標値 y で判定結果出力
         例)RL10  RL22>=50

        ・武器攻撃
        (武器記号)(技能ベース値)
         例)SW10 BX30
        武器を技能ベースでダイスロール。技発動までチェック。
        武器記号は以下の通り
         SW:剣、LS:大剣、SS:小剣、SP:槍、
         AX:斧、CL:棍棒、BW:弓、MA:体術、
         BX:ボクシング、PR:プロレス、ST:幽波紋

        ・カウンター攻撃
        カウンター技は武器記号の頭に「C」をつけるとロール可能。
         例)CSW10 CBX76
      MESSAGETEXT

      register_prefix(
        'CRL', 'CSW', 'CLS', 'CSS', 'CSP', 'CAX', 'CCL', 'CMA', 'CBX', 'CPR', 'CST',
        'RL', 'SW', 'LS', 'SS', 'SP', 'AX', 'CL', 'BW', 'MA', 'BX', 'PR', 'ST'
      )

      def eval_game_system_specific_command(command)
        m = /^([A-Z]+)([+-]?\d+)?(?:>=(\d+))?$/i.match(command)
        unless m
          return nil
        end

        weaponCommand = m[1]
        base = m[2].to_i
        diff = m[3]

        weaponInfo = getWeaponTable(weaponCommand)
        output_msg = rollJudge(base, diff, weaponInfo)

        return output_msg
      end

      def rollJudge(base, diff, weaponInfo)
        debug("rollJudge base", base)
        debug("rollJudge diff", diff)

        weaponName = weaponInfo[:name]
        weaponTable = weaponInfo[:table]

        diceList = getJudgeDiceList
        total = diceList.sum()
        allTotal = total + base

        diffText = diff.nil? ? "" : ">=#{diff}"
        result = "(#{weaponName}:#{base}#{diffText}) > 1D100+#{base} > #{total}"
        result += "[#{diceList.join(',')}]" if diceList.length >= 2
        result += "+#{base}"
        result += " > #{allTotal}"
        result += getSuccessText(allTotal, diff, diceList, weaponTable)
        result += getWeaponSkillText(weaponTable, diceList.max)

        debug("check_1D100 result", result)

        return result
      end

      def getJudgeDiceList
        diceList = []
        loop do
          value = @randomizer.roll_once(100)
          diceList << value

          rank01 = value % 10
          debug("rank01", rank01)

          break unless rank01 == 0
        end

        return diceList
      end

      def getSuccessText(allTotal, diff, diceList, isWeapon)
        first = diceList.first
        return '' if first.nil?

        return " > ファンブル" if first <= 9

        if diff.nil? && (first != 10)
          return ''
        end

        result = ''
        skillText = getSkillText(first, diff, isWeapon)
        result += skillText

        unless diff.nil?
          result += ' > ' if  skillText.empty?

          success = (allTotal >= diff.to_i ? "成功" : "失敗")
          result += success.to_s
        end

        return result
      end

      def getSkillText(first, diff, isWeapon)
        result = ''
        return result if isWeapon

        result = ' > '
        return result unless first == 10

        result += "技能なし:ファンブル"

        return result if diff.nil?

        result += "/技能あり:"

        return result\
      end

      def getWeaponTable(weaponCommand)
        debug('getWeaponTable weaponCommand', weaponCommand)

        case weaponCommand.upcase
        when 'SW'
          return getWeaponTableSword
        when 'CSW'
          return getWeaponTableSwordCounter
        when 'LS'
          return getWeaponTableLongSword
        when 'CLS'
          return getWeaponTableLongSwordCounter
        when 'SS'
          return getWeaponTableShortSword
        when 'CSS'
          return getWeaponTableShortSwordCounter
        when 'SP'
          return getWeaponTableSpear
        when 'CSP'
          return getWeaponTableSpearCounter
        when 'AX'
          return getWeaponTableAx
        when 'CAX'
          return getWeaponTableAxCounter
        when 'CL'
          return getWeaponTableClub
        when 'CCL'
          return getWeaponTableClubCounter
        when 'BW'
          return getWeaponTableBow
        when 'MA'
          return getWeaponTableMartialArt
        when 'CMA'
          return getWeaponTableMartialArtCounter
        when 'BX'
          return getWeaponTableBoxing
        when 'CBX'
          return getWeaponTableBoxingCounter
        when 'PR'
          return getWeaponTableProWrestling
        when 'CPR'
          return getWeaponTableProWrestlingCounter
        when 'ST'
          return getWeaponTableStand
        when 'CST'
          return getWeaponTableStandCounter
        end

        return {name: '判定', table: nil}
      end

      def getWeaponTableSword
        {name: '剣',
         table: [[11, '失礼剣', '成功度+5'],
                 [22, '隼斬り', '回避不可'],
                 [33, 'みじん斬り', '攻撃量2倍'],
                 [44, '天地二段', '2連続攻撃'],
                 [55, '波動剣', 'カウンター不可、B・D'],
                 [66, '疾風剣', '攻撃量3倍、盾受けー100'],
                 [77, '残像剣', '全体攻撃、B・D'],
                 [88, '五月雨斬り」', '回避不可.ダメージ3倍'],
                 [99, 'ライジングノヴア」', '2連続攻撃・2撃目敵無防備、B・D'],
                 [0, '光速剣', '攻撃量3倍、盾受け不可、カウンター不可、B・D'],]}
      end

      def getWeaponTableSwordCounter
        {name: '剣カウンター',
         table: [[33, 'パリィ', '攻撃の無効化'],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, 'かすみ青眼', 'カウンター'],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, '不動剣', 'クロスカウンター、B・D、ダメージ2倍'],]}
      end

      def getWeaponTableLongSword
        {name: '大剣',
         table: [[11, 'スマッシュ', '敵防御半分'],
                 [22, '峰打ち', '麻痺硬化「根性」0'],
                 [33, '水鳥剣', '敵防御判定ー50'],
                 [44, 'ブルクラッシュ', '敵防御力無視'],
                 [55, '逆風の太刀', 'カウンター不可、ダメージ2倍'],
                 [66, '濁流剣', '回避不可、カウンター不可、B・D'],
                 [77, '清流剣', '回避不可、カウンター不可、B・D'],
                 [88, '燕返し', '2連続攻撃・2撃目カウンター不可、B・D'],
                 [99, '地ずり残月', '盾受け不可、ダメージ3倍、B・D'],
                 [0, '乱れ雪月花', '3連続攻撃・三撃目敵無防備、ダメージ3倍、防御力無視、B・D'],]}
      end

      def getWeaponTableLongSwordCounter
        {name: '大剣カウンター',
         table: [[22, '無形の位', '攻撃の無効化'],
                 [33, nil, nil],
                 [44, nil, nil],
                 [55, '双破', 'クロスカウンター、B・D'],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, '喪心無想', 'カウンター、攻撃量6倍'],
                 [99, nil, nil],
                 [0, nil, nil],]}
      end

      def getWeaponTableShortSword
        {name: '小剣',
         table: [[11, '乱れ突き', '2連続攻撃'],
                 [22, 'フェイクタング', 'スタン効果「注意力」5'],
                 [33, 'マインドステア', '麻痺効果「注意力」0'],
                 [44, 'サイドワインダー', '成功度+3、盾受け不可'],
                 [55, 'スクリュードライバー', '防御力無視、ダメージ2倍'],
                 [66, 'ニードルロンド', '3連続攻撃'],
                 [77, 'プラズマブラスト', '麻痺効果「根性」0、B・D'],
                 [88, 'サザンクロス', '麻痺効果「根性」5、攻撃量2倍'],
                 [99, 'ファイナルレター', '気絶効果「根性」0、回避不可、カウンター不可、B・D'],
                 [0, '百花繚乱', '回避不可、盾受け不可、攻撃量3倍、B・D'],]}
      end

      def getWeaponTableShortSwordCounter
        {name: '小剣カウンター',
         table: [[11, 'リポスト', 'カウンター'],
                 [22, nil, nil],
                 [33, nil, nil],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, 'マタドール', 'カウンター、麻痺効果「注意力」5'],
                 [99, nil, nil],
                 [0, 'マリオネット', '攻撃の相手を変える'],]}
      end

      def getWeaponTableSpear
        {name: '槍',
         table: [[11, 'チャージ', 'ダメージ1.5倍、盾受けー30'],
                 [22, '稲妻突き', '回避不可'],
                 [33, '脳削り', '麻痺効果「根性」0'],
                 [44, '大車輪', '全体攻撃'],
                 [55, '狂乱撃', '二回攻撃'],
                 [66, 'スパイラルチャージ', '盾受け不可、ダメージ2倍、B・D'],
                 [77, '双龍波', 'スタン効果「注意力」5、盾受け不可、B・D'],
                 [88, '流星衝', 'カウンター不可、ダメージ3倍、次行動まで攻撃対象にならない'],
                 [99, 'ランドスライサー', '全体攻撃、回避不可、カウンター不可、B・D'],
                 [0, '無双三段', '三段攻撃、二段目B・D、三段目ダメージ2倍、B・D'],]}
      end

      def getWeaponTableSpearCounter
        {name: '槍カウンター',
         table: [[55, '風車', 'カウンター、ダメージ2倍'],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, nil, nil],]}
      end

      def getWeaponTableAx
        {name: '斧',
         table: [[11, '一人時間差', '防御行動ー100'],
                 [22, 'トマホーク', 'カウンター不可'],
                 [33, '大木断', 'ダメージ2倍'],
                 [44, 'ブレードロール', '全体攻撃'],
                 [55, 'マキ割りスペシャル', '盾受け不可、B・D'],
                 [66, 'ヨーヨー', 'カウンター不可、2連続攻撃'],
                 [77, 'メガホーク', 'カウンター不可、全体攻撃、攻撃量2倍'],
                 [88, 'デッドリースピン', '回避不可、攻撃量5倍'],
                 [99, 'マキ割りダイナミック', '盾受け不可、ダメージ2倍、B・D、ターンの最後に命中'],
                 [0, '高速ナブラ', '回避不可、カウンター不可、攻撃量3倍、B・D'],]}
      end

      def getWeaponTableAxCounter
        {name: '斧カウンター',
         table: [[44, '真っ向唐竹割り', 'クロスカウンター、B・D'],
                 [55, nil, nil],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, nil, nil],]}
      end

      def getWeaponTableClub
        {name: '棍棒',
         table: [[11, 'ハードヒット', '防御力無視'],
                 [22, 'ダブルヒット', '2連続攻撃'],
                 [33, '回転撃', '防御判定ー100'],
                 [44, '飛翔脳天撃', '麻痺効果「根性」5'],
                 [55, '削岩撃', '盾受け不可、攻撃量3倍'],
                 [66, '地裂撃', '防御力無視、カウンター不可、盾受け不可、スタン効果「注意力」0'],
                 [77, 'トリプルヒット', '3連続攻撃'],
                 [88, '亀甲羅割り', '防御力半分、盾受け不可、B・D'],
                 [99, '叩きつぶす', '防御力無視、防御行動、カウンター不可、B・D'],
                 [0, 'グランドクロス', '防御無視、盾、カウンター不可、ダメージ2倍、B・D、全体攻撃'],]}
      end

      def getWeaponTableClubCounter
        {name: '棍棒カウンター',
         table: [[11, 'ブロッキング', '攻撃の無効化'],
                 [22, nil, nil],
                 [33, nil, nil],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, 'ジャストミート', '飛び道具のみカウンター'],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, 'ホームラン', 'すべての攻撃に対するカウンター'],
                 [0, nil, nil],]}
      end

      def getWeaponTableBow
        {name: '弓',
         table: [[11, '影縫い', '麻痺効果「注意力」0'],
                 [22, 'アローレイン', '全体攻撃・回避ー50'],
                 [33, '速射', '2連続攻撃'],
                 [44, '瞬速の矢', '防御不可'],
                 [55, 'バラージシュート', '全体攻撃・盾受け不可・攻撃量2倍'],
                 [66, '貫きの矢', '防御力無視、B・D'],
                 [77, '落鳳波', '回避不可、B・D'],
                 [88, '皆死ね矢', '全体攻撃、気絶効果「根性」5'],
                 [99, 'ミリオンダラー', '三連続攻撃'],
                 [0, '夢想弓', 'B・D、ダメージ3倍'],]}
      end

      def getWeaponTableMartialArt
        {name: '体術',
         table: [[11, '集気法', '通常ダメージ分自分のHP回復'],
                 [22, 'コンビネーション', '2連続攻撃'],
                 [33, '逆一本', '盾受け不可、防御力半分、スタン効果「根性」0'],
                 [44, 'コークスクリューブロー', '防御力無視、ダメージ3倍'],
                 [55, '練気拳', '全体攻撃・回避不可'],
                 [66, 'バベルクランプル', '盾受け不可、B・D'],
                 [77, 'マシンガンジャブ', '3連続攻撃'],
                 [88, 'ナイアガラフォール', '盾受け不可、B・D、ダメージ2倍'],
                 [99, '羅刹掌', '防御力無視、防御不可、B・D、ダメージ3倍'],
                 [0, '千手観音', '5連続攻撃、すべてカウンター不可'],]}
      end

      def getWeaponTableMartialArtCounter
        {name: '体術カウンター',
         table: [[11, 'スウェイバック', '攻撃の無効化'],
                 [22, nil, nil],
                 [33, '当て身投げ', 'カウンター'],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, 'ジョルトカウンター', 'クロスカウンター、B・D'],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, 'ガードキャンセル', 'D10で振った必殺技によるカウンター' + getRandMartialArtCounter],
                 [0, nil, nil],]}
      end

      def getRandMartialArtCounter
        value = @randomizer.roll_once(10)
        dice = value * 10 + value
        dice = 100 if  value == 110

        tableInfo = getWeaponTableMartialArt
        weaponTable = tableInfo[:table]

        result = " > (#{value})"
        result += getWeaponSkillText(weaponTable, dice)

        return result
      end

      def getWeaponTableBoxing
        {name: 'ボクシング',
         table: [[11, 'ワン・ツー', '2連続攻撃・2攻撃目盾受け、回避不可'],
                 [22, 'リバーブロー', '麻痺効果「根性」5'],
                 [33, 'フリッカー', '2連続攻撃・全て盾受け、カウンター不可'],
                 [44, 'コークスクリューブロー', '防御力無視、ダメージ3倍'],
                 [55, 'レイ・ガン', '全体攻撃、B・D、陽属性魔法攻撃'],
                 [66, 'ショットガンブロー', '攻撃量10倍'],
                 [77, 'ハートブレイクショット', '2連続攻撃・1攻撃目防御力無視、ダメージ3倍・2撃目敵無防備'],
                 [88, 'デンプシーロール', '3連続攻撃・全てB・D'],
                 [99, 'フラッシュピストンマッハパンチ', '全体攻撃、B・D、気絶効果「根性」5'],
                 [0, '右', '防御力無視、ダメージ10倍'],]}
      end

      def getWeaponTableBoxingCounter
        {name: 'ボクシングカウンター',
         table: [[11, 'ダッキングブロー', 'カウンター'],
                 [22, 'ジョルトカウンター', 'クロスカウンター、B・D'],
                 [33, nil, nil],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, 'ノーガード戦法', '攻撃の無効化、次ターン以降は自分の盾受け、回避不可、全ての攻撃にB・D'],]}
      end

      def getWeaponTableProWrestling
        {name: 'プロレス',
         table: [[11, 'ボディスラム', '盾受け不可'],
                 [22, 'ドロップキック', 'B・D'],
                 [33, '水車落とし', '盾受け不可、成功度+5'],
                 [44, 'ナックルアロー', 'B・D、麻痺効果「根性」5'],
                 [55, 'ワン・ツー・エルボー', '2連続攻撃'],
                 [66, 'バックドロップ', '盾受け不可、ダメージ2倍'],
                 [77, '投げっ放しジャーマン', '盾受け不可、防御力無視、成功度+5'],
                 [88, 'パワーボム', '盾受け不可、ダメージ2倍、B・D'],
                 [99, 'デスバレーボム', '盾受け不可、防御力無視、ダメージ2倍、気絶効果「根性」5'],
                 [0, 'ジャックハマー', '盾受け不可、防御力無視、ダメージ3倍、成功度+10'],]}
      end

      def getWeaponTableProWrestlingCounter
        {name: 'プロレスカウンター',
         table: [[22, 'パワースラム', 'カウンター'],
                 [55, 'アックスボンバー', 'カウンター、B・D'],
                 [66, nil, nil],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, nil, nil],]}
      end

      def getWeaponTableStand
        {name: '幽波紋',
         table: [[11, 'SILER CHARIOT', '攻撃量5倍、刺しタイプ攻撃'],
                 [22, 'TOWER OF GRAY', '防御力無視'],
                 [33, 'DARK BLUE MOON', '全体攻撃、攻撃量2倍、水属性斬りタイプ攻撃'],
                 [44, 'EMPEROR', '回避不可、盾受け不可、カウンター不可、飛び道具攻撃'],
                 [55, 'MAGICIAN\'s RED', 'ダメージ2倍、B・D、火属性魔法攻撃'],
                 [66, 'DEATH 13', 'ダメージ0、全体攻撃、気絶効果「根性」5'],
                 [77, 'HIEROPHANT GREEN', '全体攻撃、B・D、水属性攻撃'],
                 [88, 'VANILLA ICE CREAM', '盾受け不可、カウンター不可、防御力無視、ダメージ3倍、B・D'],
                 [99, 'THE WORLD', '5連続攻撃、全て敵無防備'],
                 [0, 'STAR PLATINUM', '攻撃量15倍、B・D'],]}
      end

      def getWeaponTableStandCounter
        {name: '幽波紋カウンター',
         table: [[11, 'ANUBIS', '技のみカウンター、ダメージ(カウンターした回数の2乗)倍、斬りタイプ攻撃'],
                 [22, nil, nil],
                 [33, nil, nil],
                 [44, nil, nil],
                 [55, nil, nil],
                 [66, 'YELLOW TEMPERANE', '魔法・飛び道具含めて全ての攻撃を無効化'],
                 [77, nil, nil],
                 [88, nil, nil],
                 [99, nil, nil],
                 [0, nil, nil],]}
      end

      def getWeaponSkillText(weaponTable, dice)
        debug('getWeaponSkillText', dice)

        return '' if weaponTable.nil?

        preName = ''
        preEffect = ''

        weaponTable.each do |index, name, effect|
          name ||= preName
          preName = name

          effect ||= preEffect
          preEffect = effect

          next unless index == (dice % 100)

          return " > 「#{name}」#{effect}"
        end

        return ''
      end
    end
  end
end