bcdice 3.8.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -2
- data/lib/bcdice/game_system/Bloodorium.rb +1 -1
- data/lib/bcdice/game_system/CyberpunkRed.rb +2 -2
- data/lib/bcdice/game_system/DungeonsAndDragons5.rb +64 -10
- data/lib/bcdice/game_system/HatsuneMiku.rb +42 -1
- data/lib/bcdice/game_system/SRS.rb +79 -126
- data/lib/bcdice/game_system/ShinobiGami.rb +487 -159
- data/lib/bcdice/game_system/SkynautsBouken.rb +1 -1
- data/lib/bcdice/game_system/TenkaRyouran.rb +26 -0
- data/lib/bcdice/game_system/WorldsEndFrontline.rb +20 -0
- data/lib/bcdice/game_system.rb +2 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42944751b9e1101ab29df8042cb267f762ec4626c02d1301130716f5117ae5a1
|
4
|
+
data.tar.gz: b273615ac178eb8f8f243961604dcdd9e6eb54a3ac90d41a3adc04005dae5d45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e1e55ae455c5b0b36bd8dd5e3f4351f0ee06b195795ca44e8384c85b0fd907c682049a9d37f6b55b57a729612e0f64a1ec75a0cf437ce694a55ec6b19c46f97
|
7
|
+
data.tar.gz: ca3a7a2f2c0fd78ecc60c4b99b3d692de1deb7aa9266ac1734ad4ae96bc9399488ced485590f0b29b69ca3807c947ad371756528a22a073493f9b98977ecd2c1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 3.9.0 2023/03/25
|
4
|
+
|
5
|
+
### 対応ゲームシステムの追加
|
6
|
+
- 天下繚乱 (TenkaRyouran): 三木里 秀予さんありがとうっ! ([#604](https://github.com/bcdice/BCDice/pull/604))
|
7
|
+
- ワールドエンドフロントライン (WorldsEndFrontline): ([#611](https://github.com/bcdice/BCDice/pull/611))
|
8
|
+
|
9
|
+
### 追加機能
|
10
|
+
- 初音ミクTRPG: 表をいくつか追加。カルメヤキさんありがとうっ! ([#602](https://github.com/bcdice/BCDice/pull/602))
|
11
|
+
- スタンダードRPGシステム系: クリティカルを `@` で、ファンブルを `#` で指定できるように。三木里 秀予さんありがとうっ! ([#605](https://github.com/bcdice/BCDice/pull/605))
|
12
|
+
- ダンジョンズ&ドラゴンズ第5版: 両手持ちのダメージ算出コマンドを追加。Facelessさんありがとうっ! ([#612](https://github.com/bcdice/BCDice/pull/612))
|
13
|
+
- ダンジョンズ&ドラゴンズ第5版: 攻撃ロールでクリティカル値を指定できるように。Facelessさんありがとうっ! ([#612](https://github.com/bcdice/BCDice/pull/612))
|
14
|
+
|
15
|
+
### 変更
|
16
|
+
- シノビガミ: 変調表と戦場表の内容を改訂版に変更。 ([#588](https://github.com/bcdice/BCDice/pull/588))
|
17
|
+
|
18
|
+
### 誤植修正
|
19
|
+
- 歯車の塔の探空士(冒険企画局): 航行イベント表 困難系の誤植を修正。おさむさんありがとうっ! ([#607](https://github.com/bcdice/BCDice/pull/607))
|
20
|
+
- サイバーパンクRED: 判定コマンドに対するヘルプメッセージの誤りを修正。 ([#609](https://github.com/bcdice/BCDice/pull/609))
|
21
|
+
|
22
|
+
### バグ修正
|
23
|
+
- ブラドリウム: ダイスチェックで二桁以上のダイス数を指定できない問題を修正。ゆずあずさん指摘ありがとうっ! ([#606](https://github.com/bcdice/BCDice/pull/606))
|
24
|
+
|
3
25
|
## 3.8.0 2023/02/18
|
4
26
|
|
5
27
|
### 対応ゲームシステムの追加
|
@@ -13,7 +35,7 @@
|
|
13
35
|
|
14
36
|
### 追加機能
|
15
37
|
- ワールド・オブ・ダークネス: 振り足しの1で成功数の打ち消しが発生するコマンド(STB)を追加。フレッド緑野さんありがとうっ! ([#571](https://github.com/bcdice/BCDice/pull/571))
|
16
|
-
- トーグ エタニティ: 高揚コマンドで修正値指定が出来るように拡張。Facelessさんありがとうっ! ([#
|
38
|
+
- トーグ エタニティ: 高揚コマンドで修正値指定が出来るように拡張。Facelessさんありがとうっ! ([#580](https://github.com/bcdice/BCDice/pull/580))
|
17
39
|
- Vampire: The Masquerade 5th Edition: 判定コマンドの難易度省略時に判定結果のヒント出力を追加。フレッド緑野さんありがとうっ! ([#581](https://github.com/bcdice/BCDice/pull/581))
|
18
40
|
- Vampire: The Masquerade 5th Edition: 難易度指定時に成功差分を表示する機能を追加。フレッド緑野さんありがとうっ! ([#591](https://github.com/bcdice/BCDice/pull/591))
|
19
41
|
- 歯車の塔の探空士(冒険企画局): 航行イベント表を追加。前田さんありがとうっ! ([#601](https://github.com/bcdice/BCDice/pull/601))
|
@@ -22,7 +44,7 @@
|
|
22
44
|
- シノビガミ: ファンブル表の内容を改訂版に変更。 ([#588](https://github.com/bcdice/BCDice/pull/588))
|
23
45
|
|
24
46
|
### 誤植修正
|
25
|
-
- フタリソウサ: ヘルプメッセージにイベント表の記載漏れを追記。あまねさんありがとうっ! ([#
|
47
|
+
- フタリソウサ: ヘルプメッセージにイベント表の記載漏れを追記。あまねさんありがとうっ! ([#579](https://github.com/bcdice/BCDice/pull/579))
|
26
48
|
- ウォーハンマーRPG第4版: SLの誤植を修正。Facelessさんありがとうっ! ([#585](https://github.com/bcdice/BCDice/pull/585))
|
27
49
|
- シノビガミ: 怪変調表の誤植を修正。なす車さんありがとうっ! ([#600](https://github.com/bcdice/BCDice/pull/600))
|
28
50
|
|
@@ -16,9 +16,9 @@ module BCDice
|
|
16
16
|
|
17
17
|
# ダイスボットの使い方
|
18
18
|
HELP_MESSAGE = <<~HELP
|
19
|
-
・判定 CPx+y
|
19
|
+
・判定 CPx+y>z
|
20
20
|
(x=能力値と技能値の合計、y=修正値、z=難易度 or 受動側 x、y、zは省略可)
|
21
|
-
例)CP12 CP10+2
|
21
|
+
例)CP12 CP10+2>12 CP7-1 CP8+4 CP7>12 CP CP>9
|
22
22
|
|
23
23
|
各種表
|
24
24
|
・致命的損傷表
|
@@ -14,20 +14,26 @@ module BCDice
|
|
14
14
|
|
15
15
|
# ダイスボットの使い方
|
16
16
|
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
17
|
-
・攻撃ロール AT[x][>=t][y]
|
17
|
+
・攻撃ロール AT[x][@c][>=t][y]
|
18
18
|
x:+-修正。省略可。
|
19
|
-
|
19
|
+
c:クリティカル値。省略可。
|
20
20
|
t:敵のアーマークラス。>=を含めて省略可。
|
21
|
+
y:有利(A), 不利(D)。省略可。
|
21
22
|
ファンブル/失敗/成功/クリティカル を自動判定。
|
22
23
|
例)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
|
23
|
-
|
24
|
+
AT@19 AT+5@18 AT-2@19>=15
|
24
25
|
・能力値判定 AR[x][>=t][y]
|
25
26
|
攻撃ロールと同様。失敗/成功を自動判定。
|
26
27
|
例)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
|
27
|
-
|
28
|
+
・両手持ちのダメージ 2HnDx[m]
|
29
|
+
n:ダイスの個数
|
30
|
+
x:ダイスの面数
|
31
|
+
m:+-修正。省略可。
|
32
|
+
パラディンとファイターの武器の両手持ちによるダメージダイスの1,2の出目の振り直しを行います。
|
33
|
+
例)2H3D6 2H1D10+3 2H2D8-1
|
28
34
|
INFO_MESSAGE_TEXT
|
29
35
|
|
30
|
-
register_prefix('AT([+-]\d+)?(>=\d+)?[AD]?', 'AR([+-]\d+)?(>=\d+)?[AD]?')
|
36
|
+
register_prefix('AT([+-]\d+)?(@\d+)?(>=\d+)?[AD]?', 'AR([+-]\d+)?(>=\d+)?[AD]?', '2H(\d+)D(\d+)([+-]\d+)?')
|
31
37
|
|
32
38
|
def initialize(command)
|
33
39
|
super(command)
|
@@ -36,7 +42,7 @@ module BCDice
|
|
36
42
|
end
|
37
43
|
|
38
44
|
def eval_game_system_specific_command(command)
|
39
|
-
attack_roll(command) || ability_roll(command)
|
45
|
+
attack_roll(command) || ability_roll(command) || twohands_damage_roll(command)
|
40
46
|
end
|
41
47
|
|
42
48
|
def number_with_sign_from_int(number)
|
@@ -49,20 +55,27 @@ module BCDice
|
|
49
55
|
end
|
50
56
|
end
|
51
57
|
|
58
|
+
# 攻撃ロール
|
52
59
|
def attack_roll(command)
|
53
|
-
m = /^AT([-+]\d+)?(>=(\d+))?([AD]?)/.match(command)
|
60
|
+
m = /^AT([-+]\d+)?(@(\d+))?(>=(\d+))?([AD]?)/.match(command)
|
54
61
|
unless m
|
55
62
|
return nil
|
56
63
|
end
|
57
64
|
|
58
65
|
modify = m[1].to_i
|
59
|
-
|
60
|
-
|
66
|
+
critical_no = m[3].to_i
|
67
|
+
difficulty = m[5].to_i
|
68
|
+
advantage = m[6]
|
61
69
|
|
62
70
|
usedie = 0
|
63
71
|
roll_die = ""
|
64
72
|
|
65
73
|
dice_command = "AT#{number_with_sign_from_int(modify)}"
|
74
|
+
if critical_no > 0
|
75
|
+
dice_command += "@#{critical_no}"
|
76
|
+
else
|
77
|
+
critical_no = 20
|
78
|
+
end
|
66
79
|
if difficulty > 0
|
67
80
|
dice_command += ">=#{difficulty}"
|
68
81
|
end
|
@@ -96,7 +109,7 @@ module BCDice
|
|
96
109
|
end
|
97
110
|
|
98
111
|
result = Result.new
|
99
|
-
if usedie
|
112
|
+
if usedie >= critical_no
|
100
113
|
result.critical = true
|
101
114
|
result.success = true
|
102
115
|
output.push("クリティカル")
|
@@ -124,6 +137,7 @@ module BCDice
|
|
124
137
|
end
|
125
138
|
end
|
126
139
|
|
140
|
+
# 能力値ロール
|
127
141
|
def ability_roll(command)
|
128
142
|
m = /^AR([-+]\d+)?(>=(\d+))?([AD]?)/.match(command)
|
129
143
|
unless m
|
@@ -191,6 +205,46 @@ module BCDice
|
|
191
205
|
end
|
192
206
|
end
|
193
207
|
end
|
208
|
+
|
209
|
+
# 武器の両手持ちダメージ
|
210
|
+
def twohands_damage_roll(command)
|
211
|
+
m = /^2H(\d+)D(\d+)([+-]\d+)?/.match(command)
|
212
|
+
unless m
|
213
|
+
return nil
|
214
|
+
end
|
215
|
+
|
216
|
+
dice_count = m[1].to_i
|
217
|
+
dice_number = m[2].to_i
|
218
|
+
modify = m[3].to_i
|
219
|
+
mod_str = number_with_sign_from_int(modify)
|
220
|
+
output = ["(2H#{dice_count}D#{dice_number}#{mod_str})"]
|
221
|
+
|
222
|
+
dice = @randomizer.roll_barabara(dice_count, dice_number)
|
223
|
+
roll_dice = "[" + dice.join(",") + "]"
|
224
|
+
output.push("#{roll_dice}#{mod_str}")
|
225
|
+
|
226
|
+
ex_dice = []
|
227
|
+
new_dice = []
|
228
|
+
sum_dice = 0
|
229
|
+
dice.each do |num|
|
230
|
+
if num.to_i > 2
|
231
|
+
sum_dice += num.to_i
|
232
|
+
ex_dice.push(num)
|
233
|
+
else
|
234
|
+
one_die = @randomizer.roll_once(dice_number)
|
235
|
+
sum_dice += one_die.to_i
|
236
|
+
new_dice.push(one_die)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
unless new_dice.empty?
|
240
|
+
output.push("[" + ex_dice.join(",") + "][" + new_dice.join(",") + "]#{mod_str}")
|
241
|
+
end
|
242
|
+
output.push((sum_dice + modify).to_s)
|
243
|
+
|
244
|
+
Result.new.tap do |r|
|
245
|
+
r.text = output.join(" > ")
|
246
|
+
end
|
247
|
+
end
|
194
248
|
end
|
195
249
|
end
|
196
250
|
end
|
@@ -27,7 +27,7 @@ module BCDice
|
|
27
27
|
ネイロに5(白)を取得した場合 3:失敗
|
28
28
|
・各種表
|
29
29
|
ファンブル表 FT/致命傷表 CWT/休憩表 BT/目標表 TT/関係表 RT
|
30
|
-
障害表 OT/リクエスト表 RQT/情景表 ST
|
30
|
+
障害表 OT/リクエスト表 RQT/クロウル表 CLT/報酬表 RWT/悪夢表 NMT/情景表 ST
|
31
31
|
・キーワード表
|
32
32
|
ダーク DKT/ホット HKT/ラブ LKT/エキセントリック EKT/メランコリー MKT
|
33
33
|
・名前表 NT
|
@@ -229,6 +229,47 @@ module BCDice
|
|
229
229
|
"あなたの目の前に、あなたの死体が横たわっている。「お前を殺すものは何だ?お前は誰に殺される?」"
|
230
230
|
]
|
231
231
|
),
|
232
|
+
"CLT" => DiceTable::Table.new(
|
233
|
+
"クロウル表",
|
234
|
+
"2D6",
|
235
|
+
[
|
236
|
+
"パスワードが抜き取られていた! 所持金が無くなっている! 自分のコインを3枚失う。",
|
237
|
+
"過去に同様のオトクイと出会ったことのある人物に出会う。【技術】で判定を行う。成功すると、「特殊アプリの開発」を行うことができる(この間奏アクションには【タイム】は必要ない)。必要なコインは1枚少なくなる。",
|
238
|
+
"近所にあるパワースポットを教えてもらう。【霊力】で判定を行う。成功すると、自分の【生命力】を【活力】の値だけ回復することができる。",
|
239
|
+
"あなたのことを知る人物に出会う。どんな思い出話をしたのだろうか? この質問はリクエストとして扱う。",
|
240
|
+
"プライベートの友人からメールが届いている。【愛】で判定を行う。成功すると、好きなNPCを協力者として設定することができる。判定に失敗すると苦情のメールだった。ストレスを1点受ける。",
|
241
|
+
"ノイズメンバーから応援のメッセージをもらう。好きなネイロを1つ獲得する(この効果で。特定のネイロを7個以上にすることはできない)。",
|
242
|
+
"美味しい食べ物屋さんに関する情報を教えてもらう。【日常】で判定を行う。成功すると、自分のストレスを1点回復できる。",
|
243
|
+
"オトクイに関する情報を求めているノイズメンバーに出会う。公開されている脅威1つにつき、その情報をコイン1枚で売却できる。このイベントが2度以上起きた場合、すでに売却した脅威の情報を再び売ることはできない。",
|
244
|
+
"試作アプリの試験者を募集している。好きなアプリ1つを獲得する。ただし、このアプリを使用するときサイコロを1個振ること。1か2が出ると、そのアプリは効果を発揮しない。セッション中に、試作アプリを使用しているとセッション終了時にレポートを提出できる。【頭脳】で判定を行う。成功すると、コインを1枚獲得できる。",
|
245
|
+
"自分に関する悪口を見つける。そこには、どんな悪口が書かれていたのだろうか。 この質問は、リクエストとして扱う。",
|
246
|
+
"同じ種類のオトダマと契約しているオトダマ使いと意気投合。このセッションの間、自分のナンバー1つを、修得可能な別のナンバーに変更することができる。",
|
247
|
+
]
|
248
|
+
),
|
249
|
+
"RWT" => DiceTable::Table.new(
|
250
|
+
"報酬表",
|
251
|
+
"1D6",
|
252
|
+
[
|
253
|
+
"ノイズからオトクイ退治の報酬をもらうことができる。[倒したオトクイの本体のレベル]枚のコインを獲得する。",
|
254
|
+
"ノイズにオトダマの情報を売ることができる。[自分の【頭脳】のダイスの数]枚のコインを獲得する。",
|
255
|
+
"冒険を通じて因縁が芽生える。今回登場したキャラクターの中から一人を選ぶ。そのキャラクターを、自分の【想い人】にする。",
|
256
|
+
"冒険を通じて絆が結ばれる。今回登場したNPCの中から一人を選ぶ。そのキャラクターを、自分の【協力者】にする。",
|
257
|
+
"冒険の思い出が【ウタの欠片】になる。今回の冒険に登場した仲間、情景、出来事などなどから、キーワードを一つ選ぶ。そのキーワードを【ウタの欠片】のキーワード欄に追加する。",
|
258
|
+
"戦いの経験が【ウタの欠片】になる。今回の冒険に登場した敵、情景、出来事などなどから、キーワードを一つ選ぶ。そのキーワードを【ウタの欠片】のキーワード欄に追加する。",
|
259
|
+
]
|
260
|
+
),
|
261
|
+
"NMT" => DiceTable::Table.new(
|
262
|
+
"悪夢表",
|
263
|
+
"1D6",
|
264
|
+
[
|
265
|
+
"絶望のウタに知覚を遮断される。背後にオトクイの気配を感じたと思ったときは遅かった。卑劣な攻撃があなたを襲う。好きな能力値で判定を行う。失敗するとあなたのキャラクターは、オトナシとなり、二度と冒険に参加できない。",
|
266
|
+
"絶望のウタに混じり、悲痛な叫びが聞こえてくる。ココロダンジョンの持ち主だろうか。あなたは、救えなかったのだ。【日常】で判定を行う。失敗すると、自分の能力値一つを選ぶ。次回のセッションは、その能力値にストレスを受けた状態で始まる。",
|
267
|
+
"絶望のウタに混じり、オトクイの笑いがこだまする。それは嘲りの笑いだった。オトクイや仲間たち……何より自分への怒りがわき上がる。【日常】で判定を行う。失敗すると、自分の想い人への【想い】を一つ失う。",
|
268
|
+
"絶望のウタの中に一人取り残される。誰もあなたに気づかない。孤独に耐えながら、何とか日常へ帰還したが……そのときの恐怖がぬぐえない。【日常】で判定を行う。失敗すると、次回のセッションは、自分の【生命力】の現在値が通常の半分(端数切り上げ)の状態で始まる。",
|
269
|
+
"ココロダンジョンから帰還したあなたを待っていたのは、代わり映えのない日常だった。あなたが任務に失敗しても、世界は変わらない。なら、もう、あんな怖い目をする必要はないんじゃないか? 【日常】で判定を行う。失敗すると、自分のナンバー一つを選ぶ。次回のセッションは、そのナンバーにストレスを受けた状態で始まる。",
|
270
|
+
"絶望のウタの中を必死で逃げ出した。背後から仲間の声が聞こえた気がする。しかし、あなたは振り返ることができなかった。【日常】で判定を行う。失敗すると、自分に対して【想い】を持っているPC一人を選び、その自分に対する【想い】が失われる。",
|
271
|
+
]
|
272
|
+
),
|
232
273
|
"ST" => DiceTable::D66Table.new(
|
233
274
|
"情景表",
|
234
275
|
D66SortType::ASC,
|
@@ -16,27 +16,33 @@ module BCDice
|
|
16
16
|
|
17
17
|
HELP_MESSAGE_1 = <<~HELP_MESSAGE
|
18
18
|
・判定
|
19
|
-
・通常判定:2D6+m>=t[c,f]
|
19
|
+
・通常判定:2D6+m@c#f>=t または 2D6+m>=t[c,f]
|
20
20
|
修正値m、目標値t、クリティカル値c、ファンブル値fで判定ロールを行います。
|
21
|
-
修正値、クリティカル値、ファンブル値は省略可能です([]
|
21
|
+
修正値、クリティカル値、ファンブル値は省略可能です([]ごと省略可、@c・#fの指定は順不同)。
|
22
22
|
クリティカル値、ファンブル値の既定値は、それぞれ12、2です。
|
23
23
|
自動成功、自動失敗、成功、失敗を自動表示します。
|
24
24
|
|
25
25
|
例) 2d6>=10 修正値0、目標値10で判定
|
26
26
|
例) 2d6+2>=10 修正値+2、目標値10で判定
|
27
27
|
例) 2d6+2>=10[11] ↑をクリティカル値11で判定
|
28
|
+
例) 2d6+2@11>=10 ↑をクリティカル値11で判定
|
28
29
|
例) 2d6+2>=10[12,4] ↑をクリティカル値12、ファンブル値4で判定
|
30
|
+
例) 2d6+2@12#4>=10 ↑をクリティカル値12、ファンブル値4で判定
|
31
|
+
例) 2d6+2>=10[,4] ↑をクリティカル値12、ファンブル値4で判定(クリティカル値の省略)
|
32
|
+
例) 2d6+2#4>=10 ↑をクリティカル値12、ファンブル値4で判定(クリティカル値の省略)
|
29
33
|
HELP_MESSAGE
|
30
34
|
|
31
35
|
HELP_MESSAGE_2 = <<~HELP_MESSAGE
|
32
|
-
・クリティカルおよびファンブルのみの判定:2D6+m[c,f]
|
36
|
+
・クリティカルおよびファンブルのみの判定:2D6+m@c#f または 2D6+m[c,f]
|
33
37
|
目標値を指定せず、修正値m、クリティカル値c、ファンブル値fで判定ロールを行います。
|
34
|
-
修正値、クリティカル値、ファンブル値は省略可能です([]
|
38
|
+
修正値、クリティカル値、ファンブル値は省略可能です([]は省略不可、@c・#fの指定は順不同)。
|
35
39
|
自動成功、自動失敗を自動表示します。
|
36
40
|
|
37
41
|
例) 2d6[] 修正値0、クリティカル値12、ファンブル値2で判定
|
38
42
|
例) 2d6+2[11] 修正値+2、クリティカル値11、ファンブル値2で判定
|
43
|
+
例) 2d6+2@11 修正値+2、クリティカル値11、ファンブル値2で判定
|
39
44
|
例) 2d6+2[12,4] 修正値+2、クリティカル値12、ファンブル値4で判定
|
45
|
+
例) 2d6+2@12#4 修正値+2、クリティカル値12、ファンブル値4で判定
|
40
46
|
HELP_MESSAGE
|
41
47
|
|
42
48
|
HELP_MESSAGE_3 = <<~HELP_MESSAGE
|
@@ -50,18 +56,14 @@ module BCDice
|
|
50
56
|
|
51
57
|
# 成功判定のエイリアスコマンド定義用のクラスメソッドを提供するモジュール
|
52
58
|
module ClassMethods
|
59
|
+
# 成功判定のエイリアスコマンドの一覧
|
60
|
+
# @return [Array<String>]
|
61
|
+
attr_reader :aliases
|
62
|
+
|
53
63
|
# ダイスボットの説明文を返す
|
54
64
|
# @return [String]
|
55
65
|
attr_reader :help_message
|
56
66
|
|
57
|
-
# 目標値あり成功判定のエイリアスコマンドの正規表現を返す
|
58
|
-
# @return [Regexp, nil]
|
59
|
-
attr_reader :aliases_re_for_srs_roll_with_target_value
|
60
|
-
|
61
|
-
# 目標値なし成功判定のエイリアスコマンドの正規表現を返す
|
62
|
-
# @return [Regexp, nil]
|
63
|
-
attr_reader :aliases_re_for_srs_roll_without_target_value
|
64
|
-
|
65
67
|
# 成功判定のエイリアスコマンドを設定する
|
66
68
|
# @param [String] aliases エイリアスコマンド(可変長引数)
|
67
69
|
# @return [self]
|
@@ -70,71 +72,48 @@ module BCDice
|
|
70
72
|
# 実行時にそれが2D6に置換されるようになる。
|
71
73
|
def set_aliases_for_srs_roll(*aliases)
|
72
74
|
aliases_upcase = aliases.map(&:upcase)
|
73
|
-
aliases_part = aliases_upcase
|
74
|
-
.map { |a| Regexp.escape(a) }
|
75
|
-
.join('|')
|
76
|
-
|
77
|
-
@aliases_re_for_srs_roll_with_target_value = Regexp.new(
|
78
|
-
'\A' \
|
79
|
-
"(?:#{aliases_part})" \
|
80
|
-
'((?:[-+][-+\d]+)?>=\d+(?:\[\d*(?:,\d+)?\])?)\z'
|
81
|
-
)
|
82
|
-
|
83
|
-
@aliases_re_for_srs_roll_without_target_value = Regexp.new(
|
84
|
-
'\A' \
|
85
|
-
"(?:#{aliases_part})" \
|
86
|
-
'([-+][-+\d]+)?(\[\d*(?:,\d+)?\])?\z'
|
87
|
-
)
|
88
|
-
|
89
|
-
prepare_help_msg_for_aliases_for_srs_roll(aliases_upcase)
|
90
|
-
@help_message = concatenate_help_messages
|
91
75
|
|
76
|
+
@aliases = aliases_upcase.map { |a| Regexp.escape(a) }
|
77
|
+
@help_message = concatenate_help_messages(aliases_upcase)
|
92
78
|
return self
|
93
79
|
end
|
94
80
|
|
95
81
|
# 成功判定のエイリアスコマンドを未設定にする
|
96
82
|
# @return [self]
|
97
83
|
def clear_aliases_for_srs_roll
|
98
|
-
@
|
99
|
-
@aliases_re_for_srs_roll_without_target_value = nil
|
84
|
+
@aliases = []
|
100
85
|
@help_message = SRS::DEFAULT_HELP_MESSAGE
|
101
|
-
|
102
86
|
return self
|
103
87
|
end
|
104
88
|
|
105
89
|
private
|
106
90
|
|
107
|
-
#
|
91
|
+
# ダイスボットの説明文を結合する
|
108
92
|
# @param [Array<String>] aliases エイリアスコマンドの配列
|
109
|
-
# @return [
|
93
|
+
# @return [String] 結合された説明文
|
110
94
|
# @todo 現在は2文字のエイリアスコマンドに幅を合わせてある。
|
111
95
|
# エイリアスコマンドの文字数が変わる場合があれば、位置を調整するコードが
|
112
96
|
# 必要。
|
113
|
-
def
|
114
|
-
|
97
|
+
def concatenate_help_messages(aliases)
|
98
|
+
help_msg_for_aliases_for_target_value =
|
115
99
|
aliases
|
116
|
-
.map
|
100
|
+
.map do |a|
|
101
|
+
" 例) #{a}+2>=10 2d6+2>=10と同じ(#{a}が2D6のショートカットコマンド)\n"
|
102
|
+
end
|
117
103
|
.join()
|
118
|
-
|
119
|
-
@help_msg_for_aliases_for_srs_roll_without_target_value =
|
104
|
+
help_msg_for_aliases_for_without_target_value =
|
120
105
|
aliases
|
121
106
|
.map do |a|
|
122
107
|
" 例) #{a} 2d6[]と同じ(#{a}が2D6のショートカットコマンド)\n" \
|
123
|
-
" 例) #{a}+2
|
108
|
+
" 例) #{a}+2@12#4 2d6+2@12#4と同じ(#{a}が2D6のショートカットコマンド)\n"
|
124
109
|
end
|
125
110
|
.join()
|
126
111
|
|
127
|
-
return
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
def concatenate_help_messages
|
133
|
-
"#{SRS::HELP_MESSAGE_1}" \
|
134
|
-
"#{@help_msg_for_aliases_for_srs_roll_with_target_value}\n" \
|
135
|
-
"#{SRS::HELP_MESSAGE_2}" \
|
136
|
-
"#{@help_msg_for_aliases_for_srs_roll_without_target_value}\n" \
|
137
|
-
"#{SRS::HELP_MESSAGE_3}"
|
112
|
+
return "#{SRS::HELP_MESSAGE_1}" \
|
113
|
+
"#{help_msg_for_aliases_for_target_value}\n" \
|
114
|
+
"#{SRS::HELP_MESSAGE_2}" \
|
115
|
+
"#{help_msg_for_aliases_for_without_target_value}\n" \
|
116
|
+
"#{SRS::HELP_MESSAGE_3}"
|
138
117
|
end
|
139
118
|
end
|
140
119
|
|
@@ -153,16 +132,10 @@ module BCDice
|
|
153
132
|
DEFAULT_HELP_MESSAGE
|
154
133
|
end
|
155
134
|
|
156
|
-
#
|
157
|
-
# @return [
|
158
|
-
def
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
# 目標値なし成功判定のエイリアスコマンドの正規表現を返す
|
163
|
-
# @return [nil]
|
164
|
-
def aliases_re_for_srs_roll_without_target_value
|
165
|
-
nil
|
135
|
+
# 成功判定のエイリアスコマンドの一覧
|
136
|
+
# @return [Array<String>]
|
137
|
+
def aliases
|
138
|
+
[]
|
166
139
|
end
|
167
140
|
end
|
168
141
|
|
@@ -187,22 +160,17 @@ module BCDice
|
|
187
160
|
self.class.help_message
|
188
161
|
end
|
189
162
|
|
163
|
+
# 成功判定のエイリアスコマンドの一覧
|
164
|
+
# @return [Array<String>]
|
165
|
+
def aliases
|
166
|
+
self.class.aliases
|
167
|
+
end
|
168
|
+
|
190
169
|
# 既定のクリティカル値
|
191
170
|
DEFAULT_CRITICAL_VALUE = 12
|
192
171
|
# 既定のファンブル値
|
193
172
|
DEFAULT_FUMBLE_VALUE = 2
|
194
173
|
|
195
|
-
# 目標値あり成功判定の正規表現
|
196
|
-
SRS_ROLL_WITH_TARGET_VALUE_RE =
|
197
|
-
/\A2D6([-+][-+\d]+)?>=(\d+)(?:\[(\d+)?(?:,(\d+))?\])?\z/.freeze
|
198
|
-
# 目標値なし成功判定の正規表現
|
199
|
-
SRS_ROLL_WITHOUT_TARGET_VALUE_RE =
|
200
|
-
/\A2D6([-+][-+\d]+)?\[(\d+)?(?:,(\d+))?\]\z/.freeze
|
201
|
-
|
202
|
-
# 既定の閾値指定表記
|
203
|
-
SRS_ROLL_DEFAULT_THRESHOLDS =
|
204
|
-
"[#{DEFAULT_CRITICAL_VALUE},#{DEFAULT_FUMBLE_VALUE}]"
|
205
|
-
|
206
174
|
# 成功判定コマンドのノード
|
207
175
|
SRSRollNode = Struct.new(
|
208
176
|
:modifier, :critical_value, :fumble_value, :target_value
|
@@ -221,9 +189,15 @@ module BCDice
|
|
221
189
|
# @param [String] command 入力されたコマンド
|
222
190
|
# @return [Result, nil] ダイスロールコマンドの実行結果
|
223
191
|
def eval_game_system_specific_command(command)
|
224
|
-
|
225
|
-
|
226
|
-
|
192
|
+
legacy_c_f_match = /(.+)\[(.*)\]\z/.match(command)
|
193
|
+
node =
|
194
|
+
if legacy_c_f_match
|
195
|
+
parse_legacy(legacy_c_f_match[1], legacy_c_f_match[2])
|
196
|
+
else
|
197
|
+
parse(command)
|
198
|
+
end
|
199
|
+
|
200
|
+
if node
|
227
201
|
return execute_srs_roll(node)
|
228
202
|
end
|
229
203
|
|
@@ -232,67 +206,46 @@ module BCDice
|
|
232
206
|
|
233
207
|
private
|
234
208
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
thresholds = Regexp.last_match(2) || SRS_ROLL_DEFAULT_THRESHOLDS
|
245
|
-
|
246
|
-
return "2D6#{modifier}#{thresholds}"
|
247
|
-
else
|
248
|
-
return input
|
209
|
+
def parse(command)
|
210
|
+
prefix_re = Regexp.new(["2D6"].concat(aliases()).join('|'), Regexp::IGNORECASE)
|
211
|
+
parser = Command::Parser.new(prefix_re, round_type: @round_type)
|
212
|
+
.enable_critical
|
213
|
+
.enable_fumble
|
214
|
+
.restrict_cmp_op_to(nil, :>=)
|
215
|
+
cmd = parser.parse(command)
|
216
|
+
unless cmd
|
217
|
+
return nil
|
249
218
|
end
|
250
|
-
end
|
251
219
|
|
252
|
-
|
253
|
-
|
254
|
-
# @return [SRSRollNode, nil]
|
255
|
-
def parse(command)
|
256
|
-
case command
|
257
|
-
when SRS_ROLL_WITH_TARGET_VALUE_RE
|
258
|
-
return parse_srs_roll_with_target_value(Regexp.last_match)
|
259
|
-
when SRS_ROLL_WITHOUT_TARGET_VALUE_RE
|
260
|
-
return parse_srs_roll_without_target_value(Regexp.last_match)
|
261
|
-
else
|
220
|
+
if command.start_with?(/2D6/i) && cmd.critical.nil? && cmd.fumble.nil? && cmd.target_number.nil?
|
221
|
+
# fallback to default dice
|
262
222
|
return nil
|
263
223
|
end
|
264
|
-
end
|
265
224
|
|
266
|
-
|
267
|
-
|
268
|
-
# @return [Integer] 修正値
|
269
|
-
def eval_modifier(modifier_str)
|
270
|
-
return 0 unless modifier_str
|
225
|
+
cmd.critical ||= DEFAULT_CRITICAL_VALUE
|
226
|
+
cmd.fumble ||= DEFAULT_FUMBLE_VALUE
|
271
227
|
|
272
|
-
return
|
228
|
+
return SRSRollNode.new(cmd.modify_number, cmd.critical, cmd.fumble, cmd.target_number)
|
273
229
|
end
|
274
230
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
target_value = m[2].to_i
|
281
|
-
critical_value = m[3]&.to_i || DEFAULT_CRITICAL_VALUE
|
282
|
-
fumble_value = m[4]&.to_i || DEFAULT_FUMBLE_VALUE
|
231
|
+
def parse_legacy(command, c_f)
|
232
|
+
m = /^(-?\d+)?(?:,(-?\d+))?$/.match(c_f)
|
233
|
+
unless m
|
234
|
+
return nil
|
235
|
+
end
|
283
236
|
|
284
|
-
|
285
|
-
|
237
|
+
critical = m[1]&.to_i || DEFAULT_CRITICAL_VALUE
|
238
|
+
fumble = m[2]&.to_i || DEFAULT_FUMBLE_VALUE
|
286
239
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
240
|
+
prefix_re = Regexp.new(["2D6"].concat(aliases()).join('|'), Regexp::IGNORECASE)
|
241
|
+
parser = Command::Parser.new(prefix_re, round_type: @round_type)
|
242
|
+
.restrict_cmp_op_to(nil, :>=)
|
243
|
+
cmd = parser.parse(command)
|
244
|
+
unless cmd
|
245
|
+
return nil
|
246
|
+
end
|
294
247
|
|
295
|
-
return SRSRollNode.new(
|
248
|
+
return SRSRollNode.new(cmd.modify_number, critical, fumble, cmd.target_number)
|
296
249
|
end
|
297
250
|
|
298
251
|
# 成功判定を実行する
|