bcdice 3.3.0 → 3.6.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 +158 -74
- data/README.md +2 -1
- data/i18n/BeginningIdol/ja_jp.yml +2806 -0
- data/i18n/BeginningIdol/ko_kr.yml +1400 -0
- data/i18n/Cthulhu/zh_hans.yml +11 -0
- data/i18n/FutariSousa/ja_jp.yml +705 -9
- data/i18n/KillDeathBusiness/ja_jp.yml +2 -2
- data/i18n/MagicaLogia/ja_jp.yml +1 -1
- data/i18n/MonotoneMuseum/ko_kr.yml +526 -53
- data/i18n/SwordWorld/ja_jp.yml +6 -0
- data/i18n/SwordWorld2_0/ja_jp.yml +37 -0
- data/i18n/SwordWorld2_5/ja_jp.yml +57 -0
- data/lib/bcdice/common_command/add_dice/node.rb +28 -4
- data/lib/bcdice/common_command/add_dice/parser.rb +149 -85
- data/lib/bcdice/common_command/choice.rb +82 -7
- data/lib/bcdice/common_command/tally_dice/node.rb +135 -0
- data/lib/bcdice/common_command/tally_dice/parser.rb +302 -0
- data/lib/bcdice/common_command/tally_dice.rb +19 -0
- data/lib/bcdice/common_command.rb +2 -0
- data/lib/bcdice/dice_table/d66_left_range_table.rb +29 -0
- data/lib/bcdice/dice_table/d66_parity_table.rb +8 -0
- data/lib/bcdice/dice_table/d66_table.rb +5 -1
- data/lib/bcdice/dice_table.rb +1 -0
- data/lib/bcdice/game_system/AngelGear.rb +9 -4
- data/lib/bcdice/game_system/Aoharubaan.rb +91 -0
- data/lib/bcdice/game_system/AssaultEngine.rb +91 -0
- data/lib/bcdice/game_system/Avandner.rb +1 -2
- data/lib/bcdice/game_system/Ayabito.rb +229 -0
- data/lib/bcdice/game_system/BadLife.rb +264 -289
- data/lib/bcdice/game_system/Bakenokawa.rb +244 -0
- data/lib/bcdice/game_system/BattleTech.rb +1 -1
- data/lib/bcdice/game_system/BeginningIdol.rb +116 -2390
- data/lib/bcdice/game_system/BeginningIdol_Korean.rb +10 -2312
- data/lib/bcdice/game_system/CastleInGray.rb +133 -0
- data/lib/bcdice/game_system/Cthulhu.rb +2 -2
- data/lib/bcdice/game_system/Cthulhu7th.rb +10 -10
- data/lib/bcdice/game_system/Cthulhu_SimplifiedChinese.rb +60 -0
- data/lib/bcdice/game_system/CyberpunkRed.rb +135 -0
- data/lib/bcdice/game_system/DarkDaysDrive.rb +76 -41
- data/lib/bcdice/game_system/DoubleCross.rb +5 -0
- data/lib/bcdice/game_system/Dracurouge.rb +2 -1
- data/lib/bcdice/game_system/Elysion.rb +36 -20
- data/lib/bcdice/game_system/Emoklore.rb +1 -1
- data/lib/bcdice/game_system/FateCoreSystem.rb +117 -0
- data/lib/bcdice/game_system/FutariSousa.rb +48 -4
- data/lib/bcdice/game_system/GranCrest.rb +171 -406
- data/lib/bcdice/game_system/Irisbane.rb +154 -0
- data/lib/bcdice/game_system/Karukami.rb +84 -0
- data/lib/bcdice/game_system/KemonoNoMori.rb +17 -17
- data/lib/bcdice/game_system/KurayamiCrying.rb +1 -1
- data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
- data/lib/bcdice/game_system/NeverCloud.rb +19 -8
- data/lib/bcdice/game_system/PersonaO.rb +86 -0
- data/lib/bcdice/game_system/Revulture.rb +2 -2
- data/lib/bcdice/game_system/Shiranui.rb +145 -0
- data/lib/bcdice/game_system/ShuumatsuKikou.rb +298 -0
- data/lib/bcdice/game_system/StarryDolls.rb +318 -0
- data/lib/bcdice/game_system/SteamPunkers.rb +14 -1
- data/lib/bcdice/game_system/StellarKnights.rb +1 -1
- data/lib/bcdice/game_system/{SterileLife.rb → StellarLife.rb} +162 -226
- data/lib/bcdice/game_system/StrangerOfSwordCity.rb +18 -5
- data/lib/bcdice/game_system/SwordWorld.rb +11 -7
- data/lib/bcdice/game_system/SwordWorld2_0.rb +30 -38
- data/lib/bcdice/game_system/SwordWorld2_5.rb +9 -63
- data/lib/bcdice/game_system/TalesFromTheLoop.rb +83 -0
- data/lib/bcdice/game_system/TorgEternity.rb +2 -2
- data/lib/bcdice/game_system/ToshiakiHolyGrailWar.rb +92 -0
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +29 -28
- data/lib/bcdice/game_system/YearZeroEngine.rb +40 -19
- data/lib/bcdice/game_system/beginning_idol/accessories_table.rb +31 -0
- data/lib/bcdice/game_system/beginning_idol/bad_status_table.rb +43 -0
- data/lib/bcdice/game_system/beginning_idol/chain_d66_table.rb +29 -0
- data/lib/bcdice/game_system/beginning_idol/chain_table.rb +37 -0
- data/lib/bcdice/game_system/beginning_idol/costume_table.rb +37 -0
- data/lib/bcdice/game_system/beginning_idol/d6_twice_table.rb +36 -0
- data/lib/bcdice/game_system/beginning_idol/item_table.rb +51 -0
- data/lib/bcdice/game_system/beginning_idol/my_skill_name_table.rb +44 -0
- data/lib/bcdice/game_system/beginning_idol/random_event_table.rb +31 -0
- data/lib/bcdice/game_system/beginning_idol/skill_table.rb +63 -0
- data/lib/bcdice/game_system/beginning_idol/table.rb +193 -0
- data/lib/bcdice/game_system/beginning_idol/with_abnormality.rb +74 -0
- data/lib/bcdice/game_system/beginning_idol/work_table.rb +57 -0
- data/lib/bcdice/game_system/cyberpunk_red/tables.rb +530 -0
- data/lib/bcdice/game_system/meikyu_kingdom/tables.rb +1 -1
- data/lib/bcdice/game_system/meikyu_kingdom_basic/table.rb +1 -1
- data/lib/bcdice/game_system/one_way_heroics/random_event_table.rb +4 -4
- data/lib/bcdice/game_system/satasupe/tables.rb +1 -1
- data/lib/bcdice/game_system/sword_world/rating_options.rb +47 -0
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +40 -45
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +172 -141
- data/lib/bcdice/game_system/sword_world/transcendent_test.rb +14 -10
- data/lib/bcdice/game_system.rb +16 -1
- data/lib/bcdice/randomizer.rb +1 -1
- data/lib/bcdice/version.rb +1 -1
- metadata +45 -5
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Irisbane < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'Irisbane'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = '瞳逸らさぬイリスベイン'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'ひとみそらさぬいりすへいん'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~HELP
|
17
|
+
■攻撃判定( ATTACKx@y<=z )
|
18
|
+
x: 攻撃力
|
19
|
+
y: 判定数
|
20
|
+
z: 目標値
|
21
|
+
(※ ATTACK は ATK または AT と簡略化可能)
|
22
|
+
例) ATTACK2@3<=5
|
23
|
+
例) ATK10@2<=4
|
24
|
+
例) AT8@3<=2
|
25
|
+
|
26
|
+
上記 x y z にはそれぞれ四則演算を指定可能。
|
27
|
+
例) ATTACK2+7@3*2<=5-1
|
28
|
+
|
29
|
+
□攻撃判定のダメージ増減( ATTACKx@y<=z[+a] ATTACKx@y<=z[-a])
|
30
|
+
末尾に [+a] または [-a] と指定すると、最終的なダメージを増減できる。
|
31
|
+
a: 増減量
|
32
|
+
例) ATTACK2@3<=5[+10]
|
33
|
+
例) ATK10@2<=4[-8]
|
34
|
+
例) AT8@3<=2[-8+5]
|
35
|
+
|
36
|
+
■シチュエーション(p115)
|
37
|
+
SceneSituation, SSi
|
38
|
+
HELP
|
39
|
+
|
40
|
+
ATTACK_ROLL_REG = %r{^AT(TACK|K)?([+\-*/()\d]+)@([+\-*/()\d]+)<=([+\-*/()\d]+)(\[([+\-])([+\-*/()\d]+)\])?}i.freeze
|
41
|
+
register_prefix('AT(TACK|K)?')
|
42
|
+
|
43
|
+
def initialize(command)
|
44
|
+
super(command)
|
45
|
+
|
46
|
+
@sort_barabara_dice = true
|
47
|
+
@round_type = RoundType::CEIL
|
48
|
+
end
|
49
|
+
|
50
|
+
def eval_game_system_specific_command(command)
|
51
|
+
command = ALIAS[command] || command
|
52
|
+
|
53
|
+
if (m = ATTACK_ROLL_REG.match(command))
|
54
|
+
roll_attack(m[2], m[3], m[4], m[6], m[7])
|
55
|
+
else
|
56
|
+
roll_tables(command, TABLES)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def roll_attack(power_expression, dice_count_expression, border_expression, modification_operator, modification_expression)
|
63
|
+
power = Arithmetic.eval(power_expression, RoundType::CEIL)
|
64
|
+
dice_count = Arithmetic.eval(dice_count_expression, RoundType::CEIL)
|
65
|
+
border = Arithmetic.eval(border_expression, RoundType::CEIL)
|
66
|
+
modification_value = modification_expression.nil? ? nil : Arithmetic.eval(modification_expression, RoundType::CEIL)
|
67
|
+
return if power.nil? || dice_count.nil? || border.nil?
|
68
|
+
return if modification_operator && modification_value.nil?
|
69
|
+
|
70
|
+
power = 0 if power < 0
|
71
|
+
border = border.clamp(1, 6)
|
72
|
+
|
73
|
+
command = make_command_text(power, dice_count, border, modification_operator, modification_value)
|
74
|
+
|
75
|
+
if dice_count <= 0
|
76
|
+
return "#{command} > 判定数が 0 です"
|
77
|
+
end
|
78
|
+
|
79
|
+
dices = @randomizer.roll_barabara(dice_count, 6).sort
|
80
|
+
|
81
|
+
success_dice_count = dices.count { |dice| dice <= border }
|
82
|
+
damage = success_dice_count * power
|
83
|
+
|
84
|
+
message_elements = []
|
85
|
+
message_elements << command
|
86
|
+
message_elements << dices.join(',')
|
87
|
+
message_elements << "成功ダイス数 #{success_dice_count}"
|
88
|
+
message_elements << "× 攻撃力 #{power}" if success_dice_count > 0
|
89
|
+
|
90
|
+
if success_dice_count > 0
|
91
|
+
if modification_operator && modification_value
|
92
|
+
message_elements << "ダメージ #{damage}#{modification_operator}#{modification_value}"
|
93
|
+
damage = parse_operator(modification_operator).call(damage, modification_value)
|
94
|
+
damage = 0 if damage < 0
|
95
|
+
message_elements << damage.to_s
|
96
|
+
else
|
97
|
+
message_elements << "ダメージ #{damage}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Result.new(message_elements.join(' > ')).tap do |r|
|
102
|
+
r.condition = success_dice_count > 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_command_text(power, dice_count, border, modification_operator, modification_value)
|
107
|
+
text = "(ATTACK#{power}@#{dice_count}<=#{border}"
|
108
|
+
text += "[#{modification_operator}#{modification_value}]" if modification_operator
|
109
|
+
text += ")"
|
110
|
+
text
|
111
|
+
end
|
112
|
+
|
113
|
+
def parse_operator(operator)
|
114
|
+
case operator
|
115
|
+
when '+'
|
116
|
+
lambda { |x, y| x + y }
|
117
|
+
when '-'
|
118
|
+
lambda { |x, y| x - y }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
TABLES = {
|
123
|
+
"SceneSituation" => DiceTable::D66LeftRangeTable.new(
|
124
|
+
"シチュエーション",
|
125
|
+
BCDice::D66SortType::NO_SORT,
|
126
|
+
[
|
127
|
+
[1..3, [
|
128
|
+
"【日常】何一つ変わることの無い日々の一幕。移ろい易い世界では、それはとても大切である。",
|
129
|
+
"【準備】何かを為すための用意をする一幕。情報収集、買物遠征、やるべきことは一杯だ。",
|
130
|
+
"【趣味】自分の時間を、有効活用している一幕。必要に追われていない分、心は軽く晴れやかだ。",
|
131
|
+
"【喫茶】一息入れ、嗜好品を嗜む時の一幕。穏やかな空気は、だが、往々にして変わりやすい。",
|
132
|
+
"【鍛錬】体を鍛え、心を養う修練の一幕。己さえ良ければ、その方法も何だって良い。",
|
133
|
+
"【職務】役割の元、仕事に精を出す時の一幕。目的が何であれ、為すべきことに変わりはない。",
|
134
|
+
]],
|
135
|
+
[4..6, [
|
136
|
+
"【移動】何処かから何処かへと向かう一幕。進んでいるなら、手段も目的地も関係あるまい。",
|
137
|
+
"【墓前】故人が眠る場所へと赴く一幕。共に眠ることだけは無いように。",
|
138
|
+
"【操作】何かを操り、望みを果たしている一幕。運転にせよ何にせよ、脇見には注意が必要だ。",
|
139
|
+
"【食事】何かを糧とし、己の力を蓄える一幕。行動すれば消耗する。腹が減っては何とやらだ。",
|
140
|
+
"【休息】日々の合間の、憩いの一幕。“何もしない”というのも、立派な行いである。",
|
141
|
+
"【夢幻】現実に存在しない何かへと耽る一幕。時間帯に関わらず、何時かは必ず覚めるだろう。",
|
142
|
+
]],
|
143
|
+
]
|
144
|
+
),
|
145
|
+
}.transform_keys(&:upcase).freeze
|
146
|
+
|
147
|
+
ALIAS = {
|
148
|
+
"SSi" => "SceneSituation",
|
149
|
+
}.transform_keys(&:upcase).transform_values(&:upcase).freeze
|
150
|
+
|
151
|
+
register_prefix(TABLES.keys, ALIAS.keys)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Karukami < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'Karukami'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = 'カルカミ'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'かるかみ'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~HELP_MESSAGE
|
17
|
+
■ 行為判定、ダメージ算出 (xUB+y@c>=t)
|
18
|
+
6面ダイスをx個ダイスロールし、クリティカル値以上の出目が出たら振り足して合計値を算出します。
|
19
|
+
x: ダイス数
|
20
|
+
y: 修正値(省略可)
|
21
|
+
c: クリティカル値(省略可)
|
22
|
+
t: 目標値値(省略可)
|
23
|
+
例)2UB, 2UB>=7, 3UB+1@5, 3UB+1@5<10
|
24
|
+
HELP_MESSAGE
|
25
|
+
|
26
|
+
register_prefix('\d+UB')
|
27
|
+
|
28
|
+
def eval_game_system_specific_command(command)
|
29
|
+
roll_ub(command)
|
30
|
+
end
|
31
|
+
|
32
|
+
def roll_ub(command)
|
33
|
+
parser = Command::Parser.new("UB", round_type: @round_type)
|
34
|
+
.has_prefix_number
|
35
|
+
.enable_critical
|
36
|
+
parsed = parser.parse(command)
|
37
|
+
unless parsed
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
critical = parsed.critical || 6
|
42
|
+
if critical <= 1
|
43
|
+
return "(#{parsed}) > クリティカル値は2以上としてください"
|
44
|
+
end
|
45
|
+
|
46
|
+
list_list = []
|
47
|
+
criticals = 0
|
48
|
+
stack = parsed.prefix_number
|
49
|
+
while stack > 0
|
50
|
+
dice_list = @randomizer.roll_barabara(stack, 6)
|
51
|
+
list_list.push(dice_list)
|
52
|
+
stack = dice_list.count { |x| x >= critical }
|
53
|
+
criticals += stack
|
54
|
+
end
|
55
|
+
|
56
|
+
total = list_list.flatten.sum() + parsed.modify_number
|
57
|
+
|
58
|
+
result =
|
59
|
+
if list_list.first.all?(1)
|
60
|
+
total = 0
|
61
|
+
Result.fumble("ファンブル")
|
62
|
+
elsif parsed.cmp_op.nil?
|
63
|
+
Result.new()
|
64
|
+
elsif total.send(parsed.cmp_op, parsed.target_number)
|
65
|
+
Result.success("成功")
|
66
|
+
else
|
67
|
+
Result.failure("失敗")
|
68
|
+
end
|
69
|
+
result.critical = criticals > 0
|
70
|
+
|
71
|
+
sequence = [
|
72
|
+
"(#{parsed})",
|
73
|
+
*list_list.map { |list| "[#{list.join(',')}]" },
|
74
|
+
total,
|
75
|
+
("#{criticals}クリティカル" if result.critical?),
|
76
|
+
result.text,
|
77
|
+
].compact
|
78
|
+
|
79
|
+
result.text = sequence.join(" > ")
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -17,27 +17,27 @@ module BCDice
|
|
17
17
|
|
18
18
|
# ダイスボットの使い方
|
19
19
|
HELP_MESSAGE = <<~MESSAGETEXT
|
20
|
-
・行為判定(成功度自動算出): KAx[±y]
|
20
|
+
・行為判定(成功度自動算出)(P119): KAx[±y]
|
21
21
|
・継続判定(成功度+1固定): KCx[±y]
|
22
22
|
x=目標値
|
23
23
|
y=目標値への修正(任意) x+y-z のように複数指定可能
|
24
24
|
例1)KA7+3 → 目標値7にプラス3の修正を加えた行為判定
|
25
25
|
例2)KC6 → 目標値6の継続判定
|
26
|
-
|
27
|
-
罠ごとに1D12
|
26
|
+
・罠動作チェック+獲物表(P163): CTR
|
27
|
+
罠ごとに1D12を振り、12が出た場合には生き物が罠を動作させ、その影響を受けている。
|
28
28
|
・各種表
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
29
|
+
・大失敗表(P120): FT
|
30
|
+
・能力値ランダム決定表(P121): RST
|
31
|
+
・ランダム所要時間表(P122): RTT
|
32
|
+
・ランダム消耗表(P122): RET
|
33
|
+
・ランダム天気表(P128): RWT
|
34
|
+
・ランダム天気持続表(P128): RWDT
|
35
|
+
・ランダム遮蔽物表(屋外)(P140): ROMT
|
36
|
+
・ランダム遮蔽物表(屋内)(P140): RIMT
|
37
|
+
・逃走体験表(P144): EET
|
38
|
+
・食材採集表(P157): GFT
|
39
|
+
・水採集表(P157): GWT
|
40
|
+
・白の魔石効果表(P186): WST
|
41
41
|
MESSAGETEXT
|
42
42
|
|
43
43
|
def eval_game_system_specific_command(command)
|
@@ -106,9 +106,9 @@ module BCDice
|
|
106
106
|
[1..3, '【余裕】が3点減少する(最低0まで)'],
|
107
107
|
[4..5, 'ランダムな荷物1個が落ちて行方不明になる(大失敗したエリアのアイテム調査で見つけることが可能)'],
|
108
108
|
[6..7, 'ランダムな荷物1個が破壊される'],
|
109
|
-
[8..9, '
|
109
|
+
[8..9, 'ランダム天気表(RWT)を使用し、結果をターンの終了まで適用する'],
|
110
110
|
[10, 'ランダムな準備している小道具1個が破壊される'],
|
111
|
-
[11, '
|
111
|
+
[11, '着装している防具が破壊される'],
|
112
112
|
[12, '準備している武器が破壊される'],
|
113
113
|
]
|
114
114
|
),
|
@@ -47,7 +47,7 @@ module BCDice
|
|
47
47
|
"さっきからずっと、不気味な視線を感じる……どうやら、良くない存在に目をつけられてしまったようだ。「怪異」があなたに一方的な「ツナガリ」を獲得する。すでに「怪異」から「ツナガリ」を獲得されている場合、ダイスを振り直し、再度「アクシデント表」に当てはめる。",
|
48
48
|
"ぶつんと頭の中で音がする。あれっ?誰かのことを考えていたような……なんだか記憶が霞んで、思い出せない。あなたが獲得している「ツナガリ」をランダムに1つ失う(「継続的なツナガリ」である場合、セッション終了後に再度獲得する)。「ツナガリ」が1つもない場合、ダイスを振り直し、再度「アクシデント表」に当てはめる。",
|
49
49
|
"ぞわりと背中に懇寒が走る。自分を取り巻く「流れ」──運命に似た何かが歪んでしまったような、おぞましい予感が胸を走る。「確保」しているダイスの目が「10」になる。ダイスを「確保」していない場合、新たに「10」を「確保」する。すでに「10」の目を「確保」している場合、ダイスを振り直し、再度「アクシデント表」に当てはめる。",
|
50
|
-
"違う……違う、違う。これは自分のせいじゃない。いや、きっと何かの間違いだ。そう、あいつのせいに決まってる!進行役があなた以外の主人公をランダムに1
|
50
|
+
"違う……違う、違う。これは自分のせいじゃない。いや、きっと何かの間違いだ。そう、あいつのせいに決まってる!進行役があなた以外の主人公をランダムに1人選ぶ(誰を選んだか参加者に教えてはならない) 。選ばれた主人公が次に判定を行った際、進行役は、最も低い数字を示しているダイスの目を「10」に変更する。",
|
51
51
|
"あぁ……見つからない。アレがないとダメなのに。一体どうしたら──!「アイテム」をランダムに1つ失う(「継続品」である場合、センョン終了後に再度獲得する)。「アイテム」を1つも所持していない場合、「アイテム」を所持する主人公をランダムに1人選び、2点のダメージを与え、「アイテム」を1つ奪い取る。主人公が誰も「アイテム」を所持していない場合、「理性」を2点失う。",
|
52
52
|
"まるで自分を支える何かが失われたように、あなたはその場に立ち尽くす。諦めと絶望が心を支配する。ああ、そうか。これが、「心が折れる」ということか……。あなたは「理性」を4点失う。"
|
53
53
|
]
|
@@ -23,10 +23,10 @@ module BCDice
|
|
23
23
|
자동성공, 자동실패, 성공, 실패를 자동표기합니다.
|
24
24
|
・각종표
|
25
25
|
・감정표 ET/감정표 2.0 ET2
|
26
|
-
・징조표 OT
|
27
|
-
・일그러짐표 DT/일그러짐표ver2.0 DT2
|
28
|
-
・세계왜곡표 WDT
|
29
|
-
|
26
|
+
・징조표 OT/징조표ver2.0 OT2/징조표ver3.0 OT3
|
27
|
+
・일그러짐표 DT/일그러짐표ver2.0 DT2/일그러짐표(야외) DTO/일그러짐표(바다) DTS/일그러짐표(저택・성) DTM
|
28
|
+
・세계왜곡표 WDT/세계왜곡표2.0 WDT2
|
29
|
+
・영구소실표 EDT
|
30
30
|
・D66다이스 있음
|
31
31
|
INFO_MESSAGE_TEXT
|
32
32
|
|
@@ -19,6 +19,8 @@ module BCDice
|
|
19
19
|
|
20
20
|
# ダイスボットの使い方
|
21
21
|
HELP_MESSAGE = <<~MESSAGETEXT
|
22
|
+
・LIST のコマンドを入力して、ルールの解説・2D6表、一覧の表示
|
23
|
+
|
22
24
|
・判定(xNC±y>=z)
|
23
25
|
xD6の判定を行います。ファンブル、クリティカルの場合、その旨を出力します。
|
24
26
|
x:振るダイスの数。
|
@@ -27,7 +29,6 @@ module BCDice
|
|
27
29
|
ダイスの出目ふたつが6ならクリティカル(自動成功)
|
28
30
|
ダイスの出目すべてが1ならファンブル(自動失敗)
|
29
31
|
例) 2NC+2>=5 1NC
|
30
|
-
・ルール詳細、表の一覧(LIST)
|
31
32
|
MESSAGETEXT
|
32
33
|
|
33
34
|
def eval_game_system_specific_command(command)
|
@@ -37,6 +38,8 @@ module BCDice
|
|
37
38
|
return TEXTS[command].chomp
|
38
39
|
elsif TABLES.key?(command)
|
39
40
|
return roll_tables(command, TABLES)
|
41
|
+
elsif ALIAS_TEXTS.key?(command)
|
42
|
+
return TEXTS[ALIAS_TEXTS[command]].chomp
|
40
43
|
else
|
41
44
|
return nil
|
42
45
|
end
|
@@ -88,23 +91,27 @@ module BCDice
|
|
88
91
|
・キャラ作成アプリ:https://nctrpg.com/bloomi
|
89
92
|
|
90
93
|
・判定(xD6±y>=z)
|
94
|
+
|
95
|
+
()内のコマンドを入力して詳細を表示。
|
96
|
+
|
91
97
|
2D6(CHAR1) ・所属表(2D6またはRoC。基本ルール書籍版P33)
|
92
|
-
2D6(
|
98
|
+
2D6(CHAR2) ・趣味表(2D6またはRoC。基本ルール書籍版P38)
|
93
99
|
2D6(CHAR3) ・リビド武装形状表(2D6またはRoC。基本ルール書籍版P39)
|
94
100
|
2D6(NAYA1) 悩みの詳細表・愛/Love:得意方向(正面)(2D6またはRoC。基本ルール書籍版P49)
|
95
101
|
2D6(NAYA2) 悩みの詳細表・体/Figure:得意方向(正面)(2D6またはRoC。基本ルール書籍版P49)
|
96
102
|
2D6(NAYA3) 悩みの詳細表・才/Talent:得意方向(背面)(2D6またはRoC。基本ルール書籍版P49)
|
97
103
|
2D6(NAYA4) 悩みの詳細表・絆/Bonds:得意方向(側面)(2D6またはRoC。基本ルール書籍版P49)
|
98
104
|
2D6(NAYA5) 悩みの詳細表・住/Home:得意方向(側面)(2D6またはRoC。基本ルール書籍版P49)
|
99
|
-
各種RoC表はコマンドの最後にアルファベットのLを付けることにより一覧表示が可能
|
100
105
|
|
101
|
-
(
|
106
|
+
各種2D6:RoC表はコマンドの最後にアルファベットのLを付けて一覧表示が可能(例:NAYA5→NAYA5L)
|
107
|
+
|
108
|
+
(LIKE1) LIKE(基本ルール書籍版P60)
|
102
109
|
(RESE1) リサーチカード(基本ルール書籍版P63)
|
103
110
|
(RESE2) インタビュー(基本ルール書籍版P62)
|
104
111
|
(RESE3) パイルドライヴ(基本ルール書籍版P64)
|
105
112
|
(RESE4) [決意]と[使命](基本ルール書籍版P61)
|
106
113
|
|
107
|
-
(
|
114
|
+
(ARTS1) リビドアーツのデータ項目(基本ルール書籍版P40)
|
108
115
|
(STAT1) SSリスト(基本ルール書籍版P41)
|
109
116
|
(STAT2) LSリスト(基本ルール書籍版P411)
|
110
117
|
(ACTI1) タイミング:サブアクション(基本ルール書籍版P422)
|
@@ -132,7 +139,7 @@ module BCDice
|
|
132
139
|
(MINI5) ねばくらミニでのスペシャルアーツ(ねばくらミニ書籍版P13)
|
133
140
|
(MINI6) ねばくらミニでのポータルとサーヴァント(ねばくらミニ書籍版P14)
|
134
141
|
TEXT
|
135
|
-
'
|
142
|
+
'LIKE1' => <<~TEXT,
|
136
143
|
LIKE(基本ルール書籍版P60)
|
137
144
|
・全ての参加者(PLやGMや見学者)はセッション中にPCやGMのロールプレイや行動に、
|
138
145
|
共感や称賛や琴線に触れた時[LIKE:~]と言ってその内容と共に記述して蓄積して行く。
|
@@ -167,7 +174,7 @@ module BCDice
|
|
167
174
|
・これとは別にGMは[LIKE]の合計点を5で割った値を[使命]言う単位(最大5点)とする。
|
168
175
|
[決意]と[使命]は[Pコトノハ][Sコトノハ][ワード]の単語ごとに割り振られ、これらの単語を使用したロールプレイを推奨する。
|
169
176
|
TEXT
|
170
|
-
'
|
177
|
+
'ARTS1' => <<~TEXT,
|
171
178
|
リビドアーツのデータ項目(基本ルール書籍版P40)
|
172
179
|
・射程:起点から『ぴったり』に、何Sq離れたキャラクターを対象に取れるかを示す。射程0は自身のみのことである。
|
173
180
|
・威力:そのアーツを使用した結果に対象に及ぼす数値を示す。ダイスロールを含む場合「威力ロール」と呼ぶ。
|
@@ -602,8 +609,12 @@ module BCDice
|
|
602
609
|
),
|
603
610
|
}.freeze
|
604
611
|
|
612
|
+
ALIAS_TEXTS = {
|
613
|
+
"ARTS" => "ARTS1",
|
614
|
+
}.freeze
|
615
|
+
|
605
616
|
# ダイスボットで使用するコマンドを配列で列挙する
|
606
|
-
register_prefix('\d+NC', '\d+D6?([\+\-\d]*)>=\d+', TEXTS.keys, TABLES.keys)
|
617
|
+
register_prefix('\d+NC', '\d+D6?([\+\-\d]*)>=\d+', TEXTS.keys, TABLES.keys, ALIAS_TEXTS.keys)
|
607
618
|
end
|
608
619
|
end
|
609
620
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class PersonaO < Base
|
6
|
+
# ゲームシステムのの識別子
|
7
|
+
ID = 'PersonaO'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = 'ペルソナTRPG-O'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'へるそなTRPGO'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
17
|
+
・基本判定
|
18
|
+
PTx@y x:目標値、y:クリティカル値(省略時は5)
|
19
|
+
例)PT60 PT90@10
|
20
|
+
|
21
|
+
・ダメージ計算
|
22
|
+
nPD+(x+y*2)%(z-a)-b n:ダイス個数、x:スキル固定値、y:ボーナス、z:バフ倍率、a:耐性、b:敵防御力
|
23
|
+
nPD+(x+y*2)までがスキルによる素のダメージ、zおよびaは計算式を入れてよい。
|
24
|
+
|
25
|
+
例)ソニックパンチ、力B2点、
|
26
|
+
タルカジャがかかっており、打撃耐性あり、
|
27
|
+
目標の物理防御力は2点
|
28
|
+
|
29
|
+
2PD+(20+2*2)%(100+50-50)-2
|
30
|
+
INFO_MESSAGE_TEXT
|
31
|
+
|
32
|
+
register_prefix(
|
33
|
+
'PT',
|
34
|
+
'\d+PD'
|
35
|
+
)
|
36
|
+
|
37
|
+
def eval_game_system_specific_command(command)
|
38
|
+
roll_attack(command) || roll_damage(command)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def roll_attack(command)
|
44
|
+
m = /^PT(-?\d+)?(@(-?\d+))?$/i.match(command)
|
45
|
+
unless m
|
46
|
+
return nil
|
47
|
+
end
|
48
|
+
|
49
|
+
success_rate = m[1].to_i
|
50
|
+
critical_border = m[3]&.to_i || 5
|
51
|
+
|
52
|
+
dice_value = @randomizer.roll_once(100)
|
53
|
+
result =
|
54
|
+
if dice_value <= critical_border
|
55
|
+
Result.critical("クリティカル")
|
56
|
+
elsif dice_value <= success_rate
|
57
|
+
Result.success("成功")
|
58
|
+
else
|
59
|
+
Result.failure("失敗")
|
60
|
+
end
|
61
|
+
|
62
|
+
result.text = "D100<=#{success_rate}@#{critical_border} > #{dice_value} > #{result.text}"
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
def roll_damage(command)
|
67
|
+
m = /^(\d+)PD\+(-?\d+)%(-?\d+)-(\d+)$/i.match(command)
|
68
|
+
unless m
|
69
|
+
return nil
|
70
|
+
end
|
71
|
+
|
72
|
+
dice = m[1].to_i
|
73
|
+
kotei = m[2].to_i
|
74
|
+
hosei = m[3].to_i
|
75
|
+
bougyo = m[4].to_i
|
76
|
+
|
77
|
+
dice_list = @randomizer.roll_barabara(dice, 10)
|
78
|
+
dice_sum = dice_list.sum
|
79
|
+
|
80
|
+
dmg = dice_sum + (hosei * kotei / 100.0).to_i - bougyo
|
81
|
+
|
82
|
+
return "#{dice}D10+#{kotei}*#{hosei}%-#{bougyo} > [#{dice_list.join(',')}]+#{kotei}*#{hosei}%-#{bougyo} > #{dmg} ダメージ!"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -50,8 +50,8 @@ module BCDice
|
|
50
50
|
private
|
51
51
|
|
52
52
|
def roll_attack(dice_count_expression, border_expression, additional_damage_rules)
|
53
|
-
dice_count = Arithmetic.eval(dice_count_expression,
|
54
|
-
border = Arithmetic.eval(border_expression,
|
53
|
+
dice_count = Arithmetic.eval(dice_count_expression, RoundType::FLOOR)
|
54
|
+
border = Arithmetic.eval(border_expression, RoundType::FLOOR).clamp(1, 6) if border_expression
|
55
55
|
|
56
56
|
command = make_command_text(dice_count, border, additional_damage_rules)
|
57
57
|
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Shiranui < Base
|
6
|
+
# ゲームシステムの識別子
|
7
|
+
ID = 'Shiranui'
|
8
|
+
|
9
|
+
# ゲームシステム名
|
10
|
+
NAME = '不知火'
|
11
|
+
|
12
|
+
# ゲームシステム名の読みがな
|
13
|
+
SORT_KEY = 'しらぬい'
|
14
|
+
|
15
|
+
# ダイスボットの使い方
|
16
|
+
HELP_MESSAGE = <<~HELP
|
17
|
+
■∞D66ダイスロール
|
18
|
+
「 ∞D66 」または「 ID66 」
|
19
|
+
( ID は Infinite D の略です)
|
20
|
+
|
21
|
+
□行動力や攻撃力の指定
|
22
|
+
「 x+∞D66 」または「 x+ID66 」
|
23
|
+
( x は行動力や攻撃力)
|
24
|
+
|
25
|
+
□鬼火の使用について
|
26
|
+
鬼火を使用する∞D66は、ダイスボットでサポートしていません。
|
27
|
+
|
28
|
+
■おみくじを引く
|
29
|
+
OMKJ
|
30
|
+
HELP
|
31
|
+
|
32
|
+
INFINITE_D66_ROLL_REG = /^((\d+)\+)?(∞|I)D66$/i.freeze
|
33
|
+
register_prefix('(\d+\+)?(∞|I)D66')
|
34
|
+
|
35
|
+
def initialize(command)
|
36
|
+
super(command)
|
37
|
+
|
38
|
+
@sort_barabara_dice = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def eval_game_system_specific_command(command)
|
42
|
+
if (m = INFINITE_D66_ROLL_REG.match(command))
|
43
|
+
fixed_score = m[1]&.to_i
|
44
|
+
roll_infinite_d66(fixed_score)
|
45
|
+
else
|
46
|
+
roll_tables(command, TABLES)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def roll_infinite_d66(fixed_score)
|
51
|
+
steps = []
|
52
|
+
|
53
|
+
while steps.empty? || steps.last.to_continue_diceroll?
|
54
|
+
# 個別の出目をあつかうので、 roll_d66 ではなく roll_barabara を使う
|
55
|
+
dices = @randomizer.roll_barabara(2, 6).sort
|
56
|
+
|
57
|
+
steps << InifiniteD66Step.new(dices)
|
58
|
+
end
|
59
|
+
|
60
|
+
is_failure = steps.first.score.zero? # 「しくじり」か?
|
61
|
+
total = is_failure ? 0 : steps.sum(&:score) + fixed_score.to_i
|
62
|
+
|
63
|
+
result_text = "(#{self.class.make_command_text(fixed_score)})"
|
64
|
+
result_text += " > " + steps.map(&:to_s).join(' > ')
|
65
|
+
if is_failure
|
66
|
+
result_text += " > しくじり"
|
67
|
+
else
|
68
|
+
result_text += " > " + self.class.score_expression_text(steps, fixed_score) if steps.size > 1 || !fixed_score.nil?
|
69
|
+
result_text += " > " + total.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
Result.new(result_text).tap do |r|
|
73
|
+
r.critical = steps.size > 1
|
74
|
+
r.failure = is_failure
|
75
|
+
r.fumble = is_failure
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.make_command_text(fixed_score)
|
80
|
+
fixed_score.nil? ? "∞D66" : "#{fixed_score}+∞D66"
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.score_expression_text(steps, fixed_score)
|
84
|
+
text = steps.map(&:score).join('+')
|
85
|
+
text = "#{fixed_score}+(#{text})" unless fixed_score.nil?
|
86
|
+
text
|
87
|
+
end
|
88
|
+
|
89
|
+
class InifiniteD66Step
|
90
|
+
def initialize(dices)
|
91
|
+
@dices = dices.dup.freeze
|
92
|
+
end
|
93
|
+
|
94
|
+
def score
|
95
|
+
if repdigit?
|
96
|
+
# ゾロ目の場合
|
97
|
+
|
98
|
+
digit = @dices.first
|
99
|
+
|
100
|
+
if digit == 1
|
101
|
+
# 1 のゾロ目なら 0 となる
|
102
|
+
0
|
103
|
+
else
|
104
|
+
# 1 以外のゾロ目なら、数字の 10 倍となる
|
105
|
+
digit * 10
|
106
|
+
end
|
107
|
+
else
|
108
|
+
# ゾロ目でない場合は、 D66 様式で値を算出する
|
109
|
+
@dices[0] * 10 + @dices[1]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def repdigit?
|
114
|
+
@dices[0] == @dices[1]
|
115
|
+
end
|
116
|
+
|
117
|
+
# ダイスロールを継続する必要があるか?
|
118
|
+
def to_continue_diceroll?
|
119
|
+
repdigit? && @dices[0] != 1
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_s
|
123
|
+
"[#{@dices[0]},#{@dices[1]}]"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
TABLES = {
|
128
|
+
"OMKJ" => DiceTable::Table.new(
|
129
|
+
"おみくじ",
|
130
|
+
"1D6",
|
131
|
+
[
|
132
|
+
"大凶[御利益1]――このみくじにあたる人は、凶運から逃れることができぬ者なり。まさに凶運にその身をゆだねてこそ、浮かぶ瀬もあれ。……これより上演中に演者が振る[∞D66]で初めて⚀⚀が出たら、御利益を使っても振り直しができない。",
|
133
|
+
"凶[御利益2]――このみくじにあたる人は、吉兆を逃す定めにある。まさに、天の与うるを取らざれば反ってその咎めを受く。……これより上演中に演者が振る[∞D66]で初めて⚅⚅が出たら、強制的に1回の振り直しをする。",
|
134
|
+
"小吉[御利益3]――このみくじにあたる人は、神使の機嫌を損ねている。神使が何に怒り、何に苛立っているのかは、まさに神のみぞ知る。……神使の機嫌が突然、悪くなる。これより上演中に神使は何かと理由をつけてはシラヌイの前から立ち去ろうとする。",
|
135
|
+
"中吉[御利益4]――このみくじにあたる人は、神使の機嫌を良くすることを行った者なり。神使が何に喜び、なぜ機嫌が良いのか、まさに神のみぞ知る。……神使の機嫌がすこぶる良くなる。これより上演中に神使は上機嫌となり、シラヌイに何かにつけて話しかけてくれる。",
|
136
|
+
"吉[御利益5]――このみくじにあたる人は、悪運を幸運へと変える道を進む者なり。まさに禍福は糾える縄の如し。……これより上演中に演者が振る[∞D66]で初めて⚀⚀が出たら、御利益を消費することなく、1回の振り直しをする。",
|
137
|
+
"大吉[御利益6]――このみくじにあたる人は、思いもよらぬ幸運に巡り合う者なり。まさに、暗き道より出て、気づけば月の光あり。……これより上演中に演者が振る[∞D66]で1回だけ、サイコロの出目を⚅⚅に変えてよい。",
|
138
|
+
]
|
139
|
+
),
|
140
|
+
}.freeze
|
141
|
+
|
142
|
+
register_prefix(TABLES.keys)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|