class BCDice::GameSystem::BattleTech
Constants
- HELP_MESSAGE
ダイスボットの使い方
- HitPart
命中部位を表す構造体 @!attribute [rw] name
@return [String] 部位名
@!attribute [rw] critical_hit_may_occur
@return [Boolean] 致命的命中が発生し得るか
- ID
ゲームシステムの識別子
- LRM_LIMIT
- NAME
ゲームシステム名
- NO_CRITICAL_HIT_LIMIT
致命的命中が発生しない上限値
- SORT_KEY
ゲームシステム名の読みがな
- TABLES
表の集合
- XRM_DAMAGE_TABLES
ミサイルダメージ表
Public Class Methods
ppc_parser()
click to toggle source
@return [Command::Parser] PPCコマンドの構文解析器
# File lib/bcdice/game_system/BattleTech.rb, line 48 def self.ppc_parser return @ppc_parser if @ppc_parser @ppc_parser = Command::Parser.new(/PPC(?:[LCR][LU]?)?/, round_type: RoundType::FLOOR) @ppc_parser.enable_prefix_number @ppc_parser.restrict_cmp_op_to(:>=) @ppc_parser end
Public Instance Methods
consciousness_roll(damage)
click to toggle source
メック戦士意識維持ロールを行う
damageが6の場合は死亡。 damageが5以下の場合は、2d6の結果が意識維持表の値以上かの成功判定。
@param damage [Integer] メック戦士へのダメージ(1〜6) @return [Result] @see 「BattleTech: A Game of Armored Combat」ルールブックp. 44
# File lib/bcdice/game_system/BattleTech.rb, line 315 def consciousness_roll(damage) unless (1..6).include?(damage) return nil end command = "CD#{damage}" if damage == 6 return Result.fumble("#{command} > 死亡") end consciousness_table = { 1 => 3, 2 => 5, 3 => 7, 4 => 10, 5 => 11, } target = consciousness_table[damage] expr = "(2D6>=#{target})" values = @randomizer.roll_barabara(2, 6) sum = values.sum values_str = values.join(",") sum_and_values = "#{sum}[#{values_str}]" success = sum >= target result = success ? "成功" : "失敗" parts = [ command, expr, sum_and_values, sum, result, ] text = parts.join(" > ") return success ? Result.success(text) : Result.failure(text) end
eval_game_system_specific_command(command)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 63 def eval_game_system_specific_command(command) result = roll_tables(command, TABLES) return result if result if (ppc_parse_result = ppc_parser.parse(command)) return execute_ppc(ppc_parse_result) end count = 1 if command =~ /^(\d+)(.+)/ count = Regexp.last_match(1).to_i command = Regexp.last_match(2) end debug('executeCommandCatched count', count) debug('executeCommandCatched command', command) case command when /\ACD([1-6])\z/ damage = Regexp.last_match(1).to_i return consciousness_roll(damage) when /^((S|L)RM\d+)(.+)/ tail = Regexp.last_match(3) type = Regexp.last_match(1) damageFunc = lambda { getXrmDamage(type) } return getHitResult(count, damageFunc, tail) when /^BT(\d+)(.+)/ debug('BT pattern') tail = Regexp.last_match(2) damageValue = Regexp.last_match(1).to_i damageFunc = lambda { damageValue } return getHitResult(count, damageFunc, tail) end return nil rescue UnknownXRMError return nil end
execute_ppc(parse_result)
click to toggle source
PPCコマンドを実行する @param parse_result [Command::Parsed] PPCコマンドの構文解析結果 @return [Result, nil]
# File lib/bcdice/game_system/BattleTech.rb, line 360 def execute_ppc(parse_result) count = parse_result.prefix_number || 1 # getHitResult() の引数tailの形に合わせる # TODO: 攻撃を表すクラスに変える # "PPC" 以降の部位指定 side = parse_result.command[3..-1] modifier = Format.modifier(parse_result.modify_number) target = parse_result.target_number tail = "#{side}#{modifier}>=#{target}" # ダメージ10固定で命中判定を行う return getHitResult(count, lambda { 10 }, tail) end
getBaseValue(baseString)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 163 def getBaseValue(baseString) base = 0 return base if baseString.nil? base = ArithmeticEvaluator.eval(baseString) return base end
getDamageInfo(dice, damage, isLrm, index)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 223 def getDamageInfo(dice, damage, isLrm, index) return damage, damage.to_s if dice.nil? return damage, "[#{dice}] #{damage}" unless isLrm currentDamage = damage - (LRM_LIMIT * index) if currentDamage > LRM_LIMIT currentDamage = LRM_LIMIT end return currentDamage, currentDamage.to_s end
getDamages(damageFunc, partTable, damages)
click to toggle source
@param [Proc] damageFunc ダメージを返す手続き @param [RangeTable] partTable 命中部位表 @param [Hash] damages 蓄積したダメージの情報
# File lib/bcdice/game_system/BattleTech.rb, line 192 def getDamages(damageFunc, partTable, damages) resultText = '' damage, dice, isLrm = damageFunc.call() damagePartCount = 1 if isLrm damagePartCount = (1.0 * damage / LRM_LIMIT).ceil resultText += "[#{dice}] #{damage}点" end damagePartCount.times do |damageIndex| currentDamage, damageText = getDamageInfo(dice, damage, isLrm, damageIndex) text, part, criticalText = getHitResultOne(damageText, partTable) resultText += " " if isLrm resultText += text if damages[part].nil? damages[part] = { partDamages: [], criticals: [], } end damages[part][:partDamages] << currentDamage damages[part][:criticals] << criticalText unless criticalText.empty? end return damages, resultText end
getHitResult(count, damageFunc, tail)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 119 def getHitResult(count, damageFunc, tail) m = /\A([LCR][LU]?)?(\+\d+)?>=(\d+)/.match(tail) return nil unless m side = m[1] || 'C' baseString = m[2] target = m[3].to_i base = getBaseValue(baseString) debug("side, base, target", side, base, target) partTable = HitPart::TABLES[side] resultLines = [] damages = {} hitCount = 0 count.times do isHit, hitResult = getHitText(base, target) if isHit hitCount += 1 damages, damageText = getDamages(damageFunc, partTable, damages) hitResult += damageText end resultLines << hitResult end # 命中したか? hit = hitCount > 0 hitCountText = " > #{hitCount}回命中" hitDetails = if hit "#{hitCountText} 命中箇所:#{getTotalDamage(damages)}" else hitCountText end resultLines.push(hitDetails) resultText = resultLines.join("\n") return hit ? Result.success(resultText) : Result.failure(resultText) end
getHitResultOne(damage_text, hit_part_table)
click to toggle source
攻撃を1回行い、その結果を返す @param [String] damage_text ダメージを表す文字列 @param [RangeTable] hit_part_table 命中部位表
# File lib/bcdice/game_system/BattleTech.rb, line 276 def getHitResultOne(damage_text, hit_part_table) hit_part_roll_result = hit_part_table.roll(@randomizer) hit_part = hit_part_roll_result.content critical_hit_may_occur_str = hit_part.critical_hit_may_occur ? '(致命的命中)' : '' result_parts = [ [ "[#{hit_part_roll_result.sum}]", "#{hit_part.name}#{critical_hit_may_occur_str}", "#{damage_text}点", ].join(' ') ] criticalText = '' if hit_part.critical_hit_may_occur ct_roll_result = TABLES['CT'].roll(@randomizer) # 致命的命中が発生したか if ct_roll_result.sum > NO_CRITICAL_HIT_LIMIT criticalText = ct_roll_result.content end result_parts.push("[#{ct_roll_result.sum}] #{ct_roll_result.content}") end # TODO: 構造体で表現する return result_parts.join(' > '), hit_part.name, criticalText end
getHitText(base, target)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 171 def getHitText(base, target) dice1 = @randomizer.roll_once(6) dice2 = @randomizer.roll_once(6) total = dice1 + dice2 + base isHit = (total >= target) baseString = (base > 0 ? "+#{base}" : "") result = "#{total}[#{dice1},#{dice2}#{baseString}]>=#{target} > " if isHit result += "命中 > " else result += "外れ" end return isHit, result end
getTotalDamage(damages)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 235 def getTotalDamage(damages) parts = ['頭', '胴中央', '右胴', '左胴', '右脚', '左脚', '右腕', '左腕',] allDamage = 0 damageTexts = [] parts.each do |part| damageInfo = damages.delete(part) next if damageInfo.nil? damage = damageInfo[:partDamages].inject(0) { |sum, i| sum + i } allDamage += damage damageCount = damageInfo[:partDamages].size criticals = damageInfo[:criticals] text = "" text += "#{part}(#{damageCount}回) #{damage}点" text += " #{criticals.join(' ')}" unless criticals.empty? damageTexts << text end unless damages.empty? raise "damages rest!! #{damages.inspect()}" end result = damageTexts.join(" / ") result += " > 合計ダメージ #{allDamage}点" return result end
getXrmDamage(type)
click to toggle source
# File lib/bcdice/game_system/BattleTech.rb, line 104 def getXrmDamage(type) raise UnknownXRMError, "unknown XRM: #{type}" unless XRM_DAMAGE_TABLES.key?(type) table = XRM_DAMAGE_TABLES[type] roll_result = table.roll(@randomizer) lrm = type.start_with?('L') damage = roll_result.content modified_damage = lrm ? damage : (2 * damage) return modified_damage, roll_result.sum, lrm end
ppc_parser()
click to toggle source
@return [Command::Parser] PPCコマンドの構文解析器
# File lib/bcdice/game_system/BattleTech.rb, line 59 def ppc_parser self.class.ppc_parser end