lib/bcdice/game_system/EarthDawn4.rb
# frozen_string_literal: true
require 'bcdice/game_system/EarthDawn'
module BCDice
module GameSystem
class EarthDawn4 < EarthDawn
# ゲームシステムの識別子
ID = 'EarthDawn4'
# ゲームシステム名
NAME = 'アースドーン4版'
# ゲームシステム名の読みがな
SORT_KEY = 'ああすとおん4'
# ダイスボットの使い方
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
ステップダイス (xEnK)
ステップx、目標値n(省略可能)でステップダイスをロール。
カルマダイス使用時は末尾にKを追加(省略可能)
例)ステップ10:10E
ステップ10、目標値8:10E8
ステップ10、目標値8、カルマダイス:10E8K
INFO_MESSAGE_TEXT
register_prefix('\d+e')
def initialize(command)
super(command)
@sort_add_dice = true
@calcText = ''
end
def eval_game_system_specific_command(command)
return ed_step(command)
end
# アースドーンステップ表
def ed_step(str)
output = getStepResult(str)
return output
end
def getStepResult(str)
stepText, calcText, stepTotal, targetNumber = getStepResultInfos(str)
return nil if stepText.nil?
if targetNumber == 0
output = "#{stepText} > #{calcText} > #{stepTotal}"
return output
end
# 結果判定
successText = getSuccess(targetNumber, stepTotal)
output = "#{stepText}>=#{targetNumber} > #{calcText} > #{stepTotal} > #{successText}"
return output
end
def getStepResultInfos(str)
steps = []
calcs = []
totals = []
target = 0
while !str.nil? && !str.empty?
debug("=====>!! str", str)
step, calc, total, value, nextText = getStepResultInfo(str)
debug("=====> step", step)
return nil if step.nil?
steps << step
calcs << calc
totals << total
target = value unless value == 0
debug("=====> nextText", nextText)
break if nextText == str
str = nextText
end
stepText = steps.join("+")
calcText = calcs.join(")+(")
stepTotal = totals.inject { |sum, i| sum + i }
calcText = "(" + calcText + ")" if calcs.size > 1
calcText += " > (#{totals.join('+')})" if totals.size > 1
return stepText, calcText, stepTotal, target
end
def getStepResultInfo(str)
return nil unless /^(\d+)E(\d+)?(K)?(\+\d+$)?(\+(.*))?/i =~ str
stepTotal = 0
@isFailed = true
step = Regexp.last_match(1).to_i # ステップ
targetNumber = Regexp.last_match(2).to_i # 目標値
return nil if targetNumber < 0
hasKarmaDice = !Regexp.last_match(3).nil? # カルマダイスの有無
diceModify = Regexp.last_match(4).to_i
nextText = Regexp.last_match(6)
stepInfo = getStepInfo(step)
debug('stepInfo', stepInfo)
@calcText = ""
diceTypes = [20, 12, 10, 8, 6, 4]
diceTypes.each do |type|
stepTotal += rollStep(type, stepInfo.shift)
end
modify = stepInfo.shift
stepTotal += rollStep(6, 1) if hasKarmaDice
@calcText += (getModifyText(modify) + getModifyText(diceModify))
stepTotal += (modify + diceModify)
stepText = "ステップ#{step}"
return stepText, @calcText, stepTotal, targetNumber, nextText
end
def getModifyText(modify)
string = ""
return string if modify == 0
string += "+" if modify > 0
string += modify.to_s
return string
end
def getBaseStepTable
stepTable =
[
# dice
# D20 D12 D10 D8 D6 D4 mod
[1, [0, 0, 0, 0, 0, 1, -2]],
[2, [0, 0, 0, 0, 0, 1, -1]],
[3, [0, 0, 0, 0, 0, 1, 0]],
[4, [0, 0, 0, 0, 1, 0, 0]],
[5, [0, 0, 0, 1, 0, 0, 0]],
[6, [0, 0, 1, 0, 0, 0, 0]],
[7, [0, 1, 0, 0, 0, 0, 0]],
]
return stepTable
end
def getStepInfo(step)
baseStepTable = getBaseStepTable
baseMaxStep = baseStepTable.last.first
if step <= baseMaxStep
return get_table_by_number(step, baseStepTable)
end
# dice
# D20 D12 D10 D8 D6 D4 mod
overBounusStep = [1, 0, 0, 0, 0, 0, 0]
overStep = step - baseMaxStep - 1
stepRythm =
[
# dice
# D20 D12 D10 D8 D6 D4 mod
[0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 2, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 0, 2, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0],
[0, 2, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 1, 1, 0, 0],
[0, 1, 0, 2, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0],
]
# [ 1, 0, 0, 0, 2, 0, 0],
result = [0, 0, 0, 0, 0, 0, 0]
loopCount = (overStep / stepRythm.size)
loopCount.times do
addStepToResult(result, overBounusStep)
end
index = (overStep % stepRythm.size)
restStepInfo = stepRythm[index]
addStepToResult(result, restStepInfo)
return result
end
def addStepToResult(result, step)
result.size.times do |i|
result[i] += step[i]
end
return result
end
def getSuccess(targetNumber, stepTotal)
return '自動失敗' if @isFailed
diff = stepTotal - targetNumber
debug("diff", diff)
if diff < 0
return "失敗"
end
level = (diff / 5) + 1
return "成功 レベル:#{level}"
end
def rollStep(diceType, diceCount)
debug('rollStep diceType, diceCount, @calcText', diceType, diceCount, @calcText)
stepTotal = 0
return stepTotal unless diceCount > 0
# diceぶんのステップ判定
@calcText += "+" unless @calcText.empty?
@calcText += "#{diceCount}d#{diceType}["
debug('rollStep string', @calcText)
diceCount.times do |i|
dice_now = @randomizer.roll_once(diceType)
if dice_now != 1
@isFailed = false
end
dice_in = dice_now
while dice_now == diceType
dice_now = @randomizer.roll_once(diceType)
dice_in += dice_now
end
stepTotal += dice_in
@calcText += ',' if i != 0
@calcText += dice_in.to_s
end
@calcText += "]"
return stepTotal
end
end
end
end