Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「ダンジョンズ&ドラゴンズ第5版」のダイスボット追加 #594

Merged
merged 11 commits into from
Feb 18, 2023
Merged
1 change: 1 addition & 0 deletions lib/bcdice/game_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
require "bcdice/game_system/Dracurouge"
require "bcdice/game_system/Dracurouge_Korean"
require "bcdice/game_system/DungeonsAndDragons"
require "bcdice/game_system/DungeonsAndDragons5"
require "bcdice/game_system/EarthDawn"
require "bcdice/game_system/EarthDawn3"
require "bcdice/game_system/EarthDawn4"
Expand Down
196 changes: 196 additions & 0 deletions lib/bcdice/game_system/DungeonsAndDragons5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# frozen_string_literal: true

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

# ゲームシステム名
NAME = 'ダンジョンズ&ドラゴンズ第5版'

# ゲームシステム名の読みがな
SORT_KEY = 'たんしよんすあんととらこんす5'

# ダイスボットの使い方
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
・攻撃ロール AT[x][>=t][y]
 x:+-修正。省略可。
 y:有利(A), 不利(D)。省略可。
 t:敵のアーマークラス。>=を含めて省略可。
 ファンブル/失敗/成功/クリティカル を自動判定。
 例)AT AT>=10 AT+5>=18 AT-3>=16 ATA AT>=10A AT+3>=18A AT-3>=16 ATD AT>=10D AT+5>=18D AT-5>=16D

・能力値判定 AR[x][>=t][y]
 攻撃ロールと同様。失敗/成功を自動判定。
 例)AR AR>=10 AR+5>=18 AR-3>=16 ARA AR>=10A AR+3>=18A AR-3>=16 ARD AR>=10D AR+5>=18D AR-5>=16D

INFO_MESSAGE_TEXT

register_prefix('AT([+-]\d+)?(>=\d+)?[AD]?', 'AR([+-]\d+)?(>=\d+)?[AD]?')

def initialize(command)
super(command)

@sort_barabara_dice = false # バラバラロール(Bコマンド)でソート無
end

def eval_game_system_specific_command(command)
attack_roll(command) || ability_roll(command)
end

def number_with_sign_from_int(number)
if number == 0
return ""
elsif number > 0
return "+#{number}"
else
return number.to_s
end
end

def attack_roll(command)
m = /^AT([-+]\d+)?(>=(\d+))?([AD]?)/.match(command)
unless m
return nil
end

modify = m[1].to_i
difficulty = m[3].to_i
advantage = m[4]

usedie = 0
roll_die = ""

dice_command = "AT#{number_with_sign_from_int(modify)}"
if difficulty > 0
dice_command += ">=#{difficulty}"
end
unless advantage.empty?
dice_command += advantage.to_s
end

output = ["(#{dice_command})"]

if advantage.empty?
usedie = @randomizer.roll_once(20)
roll_die = usedie
else
dice = @randomizer.roll_barabara(2, 20)
roll_die = "[" + dice.join(",") + "]"
if advantage == "A"
usedie = dice.max
else
usedie = dice.min
end
end

if modify != 0
output.push("#{roll_die}#{number_with_sign_from_int(modify)}")
output.push((usedie + modify).to_s)
else
unless advantage.empty?
output.push(roll_die)
end
output.push(usedie.to_s)
end

result = Result.new
if usedie == 20
result.critical = true
result.success = true
output.push("クリティカル")
elsif usedie == 1
result.fumble = true
output.push("ファンブル")
elsif difficulty > 0
if usedie + modify >= difficulty
result.success = true
output.push("成功")
else
output.push("失敗")
end
end

Result.new.tap do |r|
r.text = output.join(" > ")
if result
if difficulty > 0 || result.critical? || result.fumble?
r.condition = result.success?
end
r.critical = result.critical?
r.fumble = result.fumble?
end
end
end

def ability_roll(command)
m = /^AR([-+]\d+)?(>=(\d+))?([AD]?)/.match(command)
unless m
return nil
end

modify = m[1].to_i
difficulty = m[3].to_i
advantage = m[4]

usedie = 0
roll_die = ""

dice_command = "AR#{number_with_sign_from_int(modify)}"
if difficulty > 0
dice_command += ">=#{difficulty}"
end
unless advantage.empty?
dice_command += advantage.to_s
end

output = ["(#{dice_command})"]

if advantage.empty?
usedie = @randomizer.roll_once(20)
roll_die = usedie
else
dice = @randomizer.roll_barabara(2, 20)
roll_die = "[" + dice.join(",") + "]"
if advantage == "A"
usedie = dice.max
else
usedie = dice.min
end
end

if modify != 0
output.push("#{roll_die}#{number_with_sign_from_int(modify)}")
output.push((usedie + modify).to_s)
else
unless advantage.empty?
output.push(roll_die)
end
output.push(usedie.to_s)
end

result = Result.new
if difficulty > 0
if usedie + modify >= difficulty
result.success = true
output.push("成功")
else
output.push("失敗")
end
end

Result.new.tap do |r|
r.text = output.join(" > ")
if result
if difficulty > 0
r.condition = result.success?
end
r.critical = result.critical?
r.fumble = result.fumble?
end
end
end
end
end
end
Loading