Skip to content

Commit

Permalink
Merge pull request #213 from Nokiyen/develop
Browse files Browse the repository at this point in the history
カオスフレアの専用コマンドを追加
  • Loading branch information
ysakasin authored Jun 12, 2020
2 parents 28aa43b + 305fec8 commit 6de87bc
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 5 deletions.
137 changes: 134 additions & 3 deletions src/diceBot/ChaosFlare.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true

require 'utils/command_parser'

class ChaosFlare < DiceBot
# ゲームシステムの識別子
ID = 'Chaos Flare'
Expand All @@ -12,10 +14,34 @@ class ChaosFlare < DiceBot

# ダイスボットの使い方
HELP_MESSAGE = <<INFO_MESSAGE_TEXT
失敗、成功の判定。差分値の計算も行います。
ファンブル時は達成値を-20します。
判定
CF
書式: [ダイスの数]CF[修正値][@クリティカル値][#ファンブル値][>=目標値]
CF以外は全て省略可能
例:
- CF 2D6,クリティカル値12,ファンブル値2で判定
- CF+10@10 修正値+10,クリティカル値10で判定
- CF+10#3 修正値+10,ファンブル値3で判定
- CF+10>=10 目標値を指定した場合、差分値も出力する
- 3CF+10@10#3>=10 3D6での判定
- CF@9#3+8>=10
2D6
ファンブル値2で判定する。クリティカルの判定は行われない。
目標値が設定された場合、差分値を出力する。
- 2D6+4>=10
各種表
FT: 因縁表
FTx: 数値を指定すると因果表の値を出力する
- FT -> 11から66の間でランダム決定
- FT23 -> 23の項目を出力
- FT0
- FT7
INFO_MESSAGE_TEXT

setPrefixes(['\d*CF.*', 'FT\d*'])

# ダイスボット設定後に行う処理
# @return [void]
def postSet
Expand All @@ -28,7 +54,7 @@ def postSet
end
end

# ゲーム別成功度判定(2D6)
# ゲーム別成功度判定(2D6)。以前の処理をそのまま残しています。
def check_2D6(total, dice_total, _dice_list, cmp_op, target)
output = ''

Expand All @@ -52,4 +78,109 @@ def check_2D6(total, dice_total, _dice_list, cmp_op, target)

return output
end

def rollDiceCommand(command)
if command.start_with? "FT"
roll_fate_table(command)
else
cf_roll(command)
end
end

private

# 因縁表
def roll_fate_table(command)
m = /^FT(\d+)?/.match(command)
if m[1]
num = m[1].to_i
if [0, 7].include?(num)
return "因果表(#{num}) > #{FATE_TABLE[num][0]}"
end

dice1 = num / 10
dice2 = num % 10
if !(1..6).include?(dice1) || !(1..6).include?(dice2)
return nil
end
else
dice1, = roll(1, 6)
dice2, = roll(1, 6)
end

index1 = dice1
index2 = (dice2 / 2) - 1
return "因果表(#{dice1}#{dice2}) > #{FATE_TABLE[index1][index2]}"
end

# カオスフレア専用コマンド
# @param command [String]
# @return [String, nil]
def cf_roll(command)
parser = CommandParser.new(/\d*CF/)

@cmd = parser.parse(command)
unless @cmd
return nil
end

times = @cmd.command == "CF" ? 2 : @cmd.command.to_i
critical = @cmd.critical || 12
fumble = @cmd.fumble || 2
@cmd.dollar = nil

if times < 0 || ![:>=, nil].include?(@cmd.cmp_op)
return nil
end

dice_total, dice_list_text = roll(times, 6)

is_critical = dice_total >= critical
is_fumble = dice_total <= fumble

total =
if is_critical
30
elsif is_fumble
-20
else
dice_total
end

total += @cmd.modify_number

sequence = [
"(#{@cmd.to_s(:after_modify_number)})",
"#{dice_total}[#{dice_list_text}]",
total.to_s,
("0" if total < 0),
("クリティカル" if is_critical),
("ファンブル" if is_fumble),
("差分値 #{difference(total)}" if @cmd.target_number),
].compact

return sequence.join(" > ")
end

# @param total [Integer] 合計値
# @return [Integer] 差分値
def difference(total)
if total < 0
-@cmd.target_number
else
total - @cmd.target_number
end
end

# 表を振るのに使う定数的なやつ。
FATE_TABLE = [
["腐れ縁"],
["純愛", "親近感", "庇護"],
["信頼", "感服", "共感"],
["友情", "尊敬", "慕情"],
["好敵手", "期待", "借り"],
["興味", "憎悪", "悲しみ"],
["恐怖", "執着", "利用"],
["任意"]
].freeze
end
91 changes: 91 additions & 0 deletions src/test/data/ChaosFlare.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,94 @@ input:
output:
Chaos Flare : (2D6>=7) > 9[4,5] > 9 > 成功 > 差分値2
rand:4/6,5/6
============================
input:
FT
output:
Chaos Flare : 因果表(45) > 期待
rand:4/6,5/6
============================
input:
FT45
output:
Chaos Flare : 因果表(45) > 期待
rand:
============================
input:
SFT
output:
Chaos Flare : 因果表(45) > 期待###secret dice###
rand:4/6,5/6
============================
input:
FT0
output:
Chaos Flare : 因果表(0) > 腐れ縁
rand:
============================
input:
FT7
output:
Chaos Flare : 因果表(7) > 任意
rand:
============================
input:
3CF+10+5-10@10#3>=10
output:
Chaos Flare : (3CF+5@10#3>=10) > 10[4,5,1] > 35 > クリティカル > 差分値 25
rand:4/6,5/6,1/6
============================
input:
3CF@10#3+10+5-10>=10
output:
Chaos Flare : (3CF+5@10#3>=10) > 10[4,5,1] > 35 > クリティカル > 差分値 25
rand:4/6,5/6,1/6
============================
input:
S3CF+10+5-10@10#3>=10
output:
Chaos Flare : (3CF+5@10#3>=10) > 10[4,5,1] > 35 > クリティカル > 差分値 25###secret dice###
rand:4/6,5/6,1/6
============================
input:
CF
output:
Chaos Flare : (CF) > 9[4,5] > 9
rand:4/6,5/6
============================
input:
SCF
output:
Chaos Flare : (CF) > 9[4,5] > 9###secret dice###
rand:4/6,5/6
============================
input:
3CF
output:
Chaos Flare : (3CF) > 10[4,5,1] > 10
rand:4/6,5/6,1/6
============================
input:
CF@9
output:
Chaos Flare : (CF@9) > 9[4,5] > 30 > クリティカル
rand:4/6,5/6
============================
input:
CF#5
output:
Chaos Flare : (CF#5) > 4[1,3] > -20 > 0 > ファンブル
rand:1/6,3/6
============================
input:
CF+10@10>=10
output:
Chaos Flare : (CF+10@10>=10) > 9[4,5] > 19 > 差分値 9
rand:4/6,5/6
============================
input:
CF-10@10>=10
output:
Chaos Flare : (CF-10@10>=10) > 9[4,5] > -1 > 0 > 差分値 -10
rand:4/6,5/6

50 changes: 48 additions & 2 deletions src/utils/command_parser.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
require "utils/ArithmeticEvaluator"
require "utils/normalize"
require "utils/modifier_formatter"

class CommandParser < ArithmeticEvaluator
def initialize(*literals)
@literals = literals
@round_type = :omit
end

# @!attribute [rw] command
# @return [String]
# @!attribute [rw] critical
# @return [Integer, nil]
# @!attribute [rw] fumble
# @return [Integer, nil]
# @!attribute [rw] dollar
# @return [Integer, nil]
# @!attribute [rw] modify_number
# @return [Integer]
# @!attribute [rw] cmp_op
# @return [Symbol, nil]
# @!attribute [rw] target_number
# @return [Integer, nil]
class Parsed
attr_accessor :command, :critical, :fumble, :dollar, :modify_number, :cmp_op, :target_number

include ModifierFormatter

def initialize
@critical = nil
@fumble = nil
@dollar = nil
end

def to_s(suffix_position = :after_command)
c = @critical ? "@#{@critical}" : nil
f = @fumble ? "##{@fumble}" : nil
d = @dollar ? "$#{@dollar}" : nil
m = format_modifier(@modify_number)

case suffix_position
when :after_command
[@command, c, f, d, m, @cmp_op, @target_number].join()
when :after_modify_number
[@command, m, c, f, d, @cmp_op, @target_number].join()
when :after_target_number
[@command, m, @cmp_op, @target_number, c, f, d].join()
end
end
end

# @param expr [String]
# @param rount_type [Symbol]
# @return [CommandParser::Parsed]
# @return [nil]
def parse(expr, round_type = :omit)
@tokens = tokenize(expr)
@idx = 0
Expand All @@ -30,10 +77,9 @@ def parse(expr, round_type = :omit)
return @parsed
end

Parsed = Struct.new(:command, :critical, :fumble, :dollar, :modify_number, :cmp_op, :target_number)

private

# @return [Array<String>]
def tokenize(expr)
expr.gsub(%r{[\(\)\+\-*/@#\$]|[<>!=]+}) { |e| " #{e} " }.split(' ')
end
Expand Down

0 comments on commit 6de87bc

Please sign in to comment.