bcdice 3.11.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -0
- data/i18n/FutariSousa/ko_kr.yml +1625 -529
- data/i18n/Insane/ko_kr.yml +393 -258
- data/i18n/NinjaSlayer2/ja_jp.yml +34 -0
- data/lib/bcdice/arithmetic/parser.rb +4 -2
- data/lib/bcdice/base.rb +1 -1
- data/lib/bcdice/command/parser.rb +4 -2
- data/lib/bcdice/common_command/add_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/barabara_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/calc/parser.rb +4 -2
- data/lib/bcdice/common_command/reroll_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/tally_dice/parser.rb +4 -2
- data/lib/bcdice/common_command/upper_dice/parser.rb +4 -2
- data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
- data/lib/bcdice/game_system/Alsetto.rb +2 -2
- data/lib/bcdice/game_system/AniMalus.rb +221 -0
- data/lib/bcdice/game_system/ArknightsFan.rb +182 -0
- data/lib/bcdice/game_system/Avandner.rb +1 -1
- data/lib/bcdice/game_system/BBN.rb +1 -1
- data/lib/bcdice/game_system/BadLife.rb +3 -3
- data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
- data/lib/bcdice/game_system/Chill3.rb +6 -6
- data/lib/bcdice/game_system/DarkSouls.rb +1 -1
- data/lib/bcdice/game_system/Elric.rb +1 -1
- data/lib/bcdice/game_system/Emoklore.rb +4 -6
- data/lib/bcdice/game_system/FullFace.rb +92 -0
- data/lib/bcdice/game_system/FutariSousa_Korean.rb +44 -19
- data/lib/bcdice/game_system/HunterTheReckoning5th.rb +10 -3
- data/lib/bcdice/game_system/InfiniteFantasia.rb +4 -1
- data/lib/bcdice/game_system/Insane_Korean.rb +11 -11
- data/lib/bcdice/game_system/Irisbane.rb +1 -1
- data/lib/bcdice/game_system/KamitsubakiCityUnderConstructionNarrative.rb +251 -0
- data/lib/bcdice/game_system/KillDeathBusiness.rb +1 -1
- data/lib/bcdice/game_system/KyokoShinshoku.rb +158 -0
- data/lib/bcdice/game_system/Liminal.rb +136 -0
- data/lib/bcdice/game_system/MetalHead.rb +1 -1
- data/lib/bcdice/game_system/MetalHeadExtream.rb +1 -1
- data/lib/bcdice/game_system/NRR.rb +122 -0
- data/lib/bcdice/game_system/NSSQ.rb +1 -1
- data/lib/bcdice/game_system/NightWizard.rb +1 -1
- data/lib/bcdice/game_system/NightWizard3rd.rb +15 -2
- data/lib/bcdice/game_system/NinjaSlayer.rb +3 -1
- data/lib/bcdice/game_system/NinjaSlayer2.rb +299 -0
- data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
- data/lib/bcdice/game_system/PastFutureParadox.rb +1238 -0
- data/lib/bcdice/game_system/Postman.rb +3 -3
- data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
- data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +10 -7
- data/lib/bcdice/game_system/Ryutama.rb +4 -4
- data/lib/bcdice/game_system/SajinsenkiAGuS.rb +5 -1
- data/lib/bcdice/game_system/SajinsenkiAGuS2E.rb +285 -0
- data/lib/bcdice/game_system/Siren.rb +97 -0
- data/lib/bcdice/game_system/Skynauts.rb +1 -1
- data/lib/bcdice/game_system/SkynautsBouken.rb +1 -1
- data/lib/bcdice/game_system/Strave.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +16 -0
- data/lib/bcdice/game_system/SwordWorld2_5.rb +8 -1
- data/lib/bcdice/game_system/TherapieSein.rb +1 -1
- data/lib/bcdice/game_system/TrinitySeven.rb +1 -1
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +21 -9
- data/lib/bcdice/game_system/WerewolfTheApocalypse5th.rb +179 -0
- data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +1 -1
- data/lib/bcdice/game_system/sword_world/rating_options.rb +3 -0
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +9 -0
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +177 -130
- data/lib/bcdice/game_system/sword_world/transcendent_test.rb +1 -1
- data/lib/bcdice/game_system.rb +12 -0
- data/lib/bcdice/loader.rb +1 -1
- data/lib/bcdice/version.rb +1 -1
- metadata +32 -5
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class KamitsubakiCityUnderConstructionNarrative < Base
|
|
6
|
+
# ゲームシステムの識別子
|
|
7
|
+
ID = 'KamitsubakiCityUnderConstructionNarrative'
|
|
8
|
+
|
|
9
|
+
# ゲームシステム名
|
|
10
|
+
NAME = '神椿市建設中。NARRATIVE'
|
|
11
|
+
|
|
12
|
+
# ゲームシステム名の読みがな
|
|
13
|
+
SORT_KEY = 'かみつはきしけんせつちゆうならていふ'
|
|
14
|
+
|
|
15
|
+
# ダイスボットの使い方
|
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
|
17
|
+
・可組(KA)
|
|
18
|
+
KA6 行動判定
|
|
19
|
+
KA8 技能ロール
|
|
20
|
+
KA10 特技ロール
|
|
21
|
+
KA12 Aロール
|
|
22
|
+
|
|
23
|
+
・裏組(RI)
|
|
24
|
+
RI6 行動判定
|
|
25
|
+
RI8 技能ロール
|
|
26
|
+
RI10 特技ロール
|
|
27
|
+
RI12 Aロール
|
|
28
|
+
|
|
29
|
+
・羽組(HA)
|
|
30
|
+
HA6 行動判定
|
|
31
|
+
HA8 技能ロール
|
|
32
|
+
HA10 特技ロール
|
|
33
|
+
HA12 Aロール
|
|
34
|
+
|
|
35
|
+
・星組(SE)
|
|
36
|
+
SE6 行動判定
|
|
37
|
+
SE8 技能ロール
|
|
38
|
+
SE10 特技ロール
|
|
39
|
+
SE12 Aロール
|
|
40
|
+
|
|
41
|
+
・狐組(CO)
|
|
42
|
+
CO6 行動判定
|
|
43
|
+
CO8 技能ロール
|
|
44
|
+
CO10 特技ロール
|
|
45
|
+
CO12 Aロール
|
|
46
|
+
|
|
47
|
+
・GM用
|
|
48
|
+
GM6 (成否判定なし)
|
|
49
|
+
GM8 技能ロール
|
|
50
|
+
GM10 特技ロール
|
|
51
|
+
Q12 Qロール
|
|
52
|
+
|
|
53
|
+
・存在証明 EXI<=x
|
|
54
|
+
存在証明の判定を行う
|
|
55
|
+
x: 存在値
|
|
56
|
+
INFO_MESSAGE_TEXT
|
|
57
|
+
|
|
58
|
+
def eval_game_system_specific_command(command)
|
|
59
|
+
roll_kumi(command) || roll_existence(command)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def roll_kumi(command)
|
|
65
|
+
table = TABLES[command]
|
|
66
|
+
unless table
|
|
67
|
+
return nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
return table.roll(@randomizer)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class KumiDice
|
|
74
|
+
def initialize(items)
|
|
75
|
+
@items = items.freeze
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
CRITICAL = "M"
|
|
79
|
+
FUMBLE = "Q"
|
|
80
|
+
|
|
81
|
+
def roll(randomizer)
|
|
82
|
+
dice = randomizer.roll_once(@items.length)
|
|
83
|
+
chosen = @items[dice - 1]
|
|
84
|
+
|
|
85
|
+
fumble = chosen == FUMBLE
|
|
86
|
+
critical = chosen == CRITICAL
|
|
87
|
+
|
|
88
|
+
result_tail =
|
|
89
|
+
if fumble
|
|
90
|
+
"ファンブル"
|
|
91
|
+
elsif critical
|
|
92
|
+
"マジック"
|
|
93
|
+
elsif !chosen.empty?
|
|
94
|
+
"成功"
|
|
95
|
+
else
|
|
96
|
+
"失敗"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Result.new.tap do |r|
|
|
100
|
+
r.critical = critical
|
|
101
|
+
r.fumble = fumble
|
|
102
|
+
r.condition = !chosen.empty? && !r.fumble?
|
|
103
|
+
r.text = [
|
|
104
|
+
"(D#{@items.length})",
|
|
105
|
+
dice,
|
|
106
|
+
chosen.empty? ? nil : chosen,
|
|
107
|
+
result_tail
|
|
108
|
+
].compact.join(" > ")
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class KumiD6
|
|
114
|
+
def initialize(success_symbol)
|
|
115
|
+
@success_symbol = success_symbol
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
TABLE = ["裏", "羽", "星", "狐", "可", "Q"].freeze
|
|
119
|
+
|
|
120
|
+
def roll(randomizer)
|
|
121
|
+
dice = randomizer.roll_once(6)
|
|
122
|
+
chosen = TABLE[dice - 1]
|
|
123
|
+
|
|
124
|
+
Result.new.tap do |r|
|
|
125
|
+
unless @success_symbol.nil?
|
|
126
|
+
r.fumble = chosen == "Q"
|
|
127
|
+
r.condition = chosen == @success_symbol
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
result_tail =
|
|
131
|
+
if r.fumble?
|
|
132
|
+
"ファンブル"
|
|
133
|
+
elsif r.success?
|
|
134
|
+
"成功"
|
|
135
|
+
elsif r.failure?
|
|
136
|
+
"失敗"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
r.text = [
|
|
140
|
+
"(D6)",
|
|
141
|
+
dice,
|
|
142
|
+
chosen,
|
|
143
|
+
result_tail
|
|
144
|
+
].compact.join(" > ")
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
class QDice
|
|
150
|
+
def initialize(items)
|
|
151
|
+
@items = items.freeze
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
CRITICAL = "M"
|
|
155
|
+
|
|
156
|
+
def roll(randomizer)
|
|
157
|
+
dice = randomizer.roll_once(@items.length)
|
|
158
|
+
chosen = @items[dice - 1]
|
|
159
|
+
|
|
160
|
+
critical = chosen == CRITICAL
|
|
161
|
+
|
|
162
|
+
result_tail =
|
|
163
|
+
if critical
|
|
164
|
+
"マジック"
|
|
165
|
+
elsif !chosen.empty?
|
|
166
|
+
"成功"
|
|
167
|
+
else
|
|
168
|
+
"失敗"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
Result.new.tap do |r|
|
|
172
|
+
r.critical = critical
|
|
173
|
+
r.condition = !chosen.empty?
|
|
174
|
+
r.text = [
|
|
175
|
+
"(D#{@items.length})",
|
|
176
|
+
dice.to_s,
|
|
177
|
+
chosen.empty? ? nil : chosen,
|
|
178
|
+
result_tail,
|
|
179
|
+
].compact.join(" > ")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def roll_existence(command)
|
|
185
|
+
m = /^EXI<=(\d+)$/.match(command)
|
|
186
|
+
unless m
|
|
187
|
+
return nil
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
target = m[1].to_i
|
|
191
|
+
dice = @randomizer.roll_once(20)
|
|
192
|
+
Result.new.tap do |r|
|
|
193
|
+
r.critical = dice == 1
|
|
194
|
+
r.fumble = dice == 20
|
|
195
|
+
r.condition = (dice <= target && !r.fumble?) || r.critical?
|
|
196
|
+
|
|
197
|
+
result_tail =
|
|
198
|
+
if r.critical?
|
|
199
|
+
"M > マジック"
|
|
200
|
+
elsif r.fumble?
|
|
201
|
+
"Q > ファンブル"
|
|
202
|
+
elsif r.success?
|
|
203
|
+
"成功"
|
|
204
|
+
else
|
|
205
|
+
"失敗"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
r.text = [
|
|
209
|
+
"(D20<=#{target})",
|
|
210
|
+
dice,
|
|
211
|
+
result_tail
|
|
212
|
+
].join(" > ")
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
TABLES = {
|
|
217
|
+
"KA6" => KumiD6.new("可"),
|
|
218
|
+
"KA8" => KumiDice.new(["Q", "", "", "", "可", "可", "可", "M"]),
|
|
219
|
+
"KA10" => KumiDice.new(["Q", "", "", "可", "可", "可", "可", "可", "M", "M"]),
|
|
220
|
+
"KA12" => KumiDice.new(["Q", "", "", "可", "可", "可", "可", "可", "可", "可", "M", "M"]),
|
|
221
|
+
|
|
222
|
+
"RI6" => KumiD6.new("裏"),
|
|
223
|
+
"RI8" => KumiDice.new(["Q", "", "", "", "裏", "裏", "裏", "M"]),
|
|
224
|
+
"RI10" => KumiDice.new(["Q", "", "", "裏", "裏", "裏", "裏", "裏", "M", "M"]),
|
|
225
|
+
"RI12" => KumiDice.new(["M", "M", "裏", "裏", "裏", "裏", "裏", "裏", "裏", "", "", "Q"]),
|
|
226
|
+
|
|
227
|
+
"HA6" => KumiD6.new("羽"),
|
|
228
|
+
"HA8" => KumiDice.new(["Q", "", "", "", "羽", "羽", "羽", "M"]),
|
|
229
|
+
"HA10" => KumiDice.new(["Q", "", "", "羽", "羽", "羽", "羽", "羽", "M", "M"]),
|
|
230
|
+
"HA12" => KumiDice.new(["Q", "Q", "羽", "羽", "羽", "", "", "", "M", "M", "M", "M"]),
|
|
231
|
+
|
|
232
|
+
"SE6" => KumiD6.new("星"),
|
|
233
|
+
"SE8" => KumiDice.new(["Q", "", "", "", "星", "星", "星", "M"]),
|
|
234
|
+
"SE10" => KumiDice.new(["Q", "", "", "星", "星", "星", "星", "星", "M", "M"]),
|
|
235
|
+
"SE12" => KumiDice.new(["星", "", "星", "星", "M", "Q", "M", "星", "星", "星", "", "星"]),
|
|
236
|
+
|
|
237
|
+
"CO6" => KumiD6.new("狐"),
|
|
238
|
+
"CO8" => KumiDice.new(["Q", "", "", "", "狐", "狐", "狐", "M"]),
|
|
239
|
+
"CO10" => KumiDice.new(["Q", "", "", "狐", "狐", "狐", "狐", "狐", "M", "M"]),
|
|
240
|
+
"CO12" => KumiDice.new(["Q", "", "", "狐狐狐", "狐狐", "狐", "狐狐狐", "狐狐", "狐", "狐", "M", "M"]),
|
|
241
|
+
|
|
242
|
+
"GM6" => KumiD6.new(nil),
|
|
243
|
+
"GM8" => KumiDice.new(["Q", "", "", "", "W", "W", "W", "M"]),
|
|
244
|
+
"GM10" => KumiDice.new(["Q", "", "", "W", "W", "W", "W", "W", "M", "M"]),
|
|
245
|
+
"Q12" => QDice.new(["", "", "", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "M", "M"])
|
|
246
|
+
}.freeze
|
|
247
|
+
|
|
248
|
+
register_prefix("EXI", TABLES.keys)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class KyokoShinshoku < Base
|
|
6
|
+
# ゲームシステムの識別子
|
|
7
|
+
ID = "KyokoShinshoku"
|
|
8
|
+
|
|
9
|
+
# ゲームシステム名
|
|
10
|
+
NAME = "虚構侵蝕TRPG"
|
|
11
|
+
|
|
12
|
+
# ゲームシステム名の読みがな
|
|
13
|
+
SORT_KEY = "きよこうしんしよくTRPG"
|
|
14
|
+
|
|
15
|
+
# ダイスボットの使い方
|
|
16
|
+
HELP_MESSAGE = <<~MESSAGETEXT
|
|
17
|
+
・判定
|
|
18
|
+
ダイスを指定数ダイスロールして、最も高い出目を出力します。難易度を指定すると成否を判定します。
|
|
19
|
+
KS(x,y)
|
|
20
|
+
x:ダイスサイズ。1=D4(能力値1、2以上の出目が出ていたとしても最大1)/2=D4(能力値2、3以上の出目が出ていたとしても最大2)/3=D4(能力値3、出目4が出ていたとしても最大3)/4=D4/6=D6/8=D8/10=D10/12=D12/20=D20
|
|
21
|
+
y:ダイス数(省略:1)
|
|
22
|
+
|
|
23
|
+
KS(x,y)>=z
|
|
24
|
+
x:ダイスサイズ。1=D4(能力値1、2以上の出目が出ていたとしても最大1)/2=D4(能力値2、3以上の出目が出ていたとしても最大2)/3=D4(能力値3、出目4が出ていたとしても最大3)/4=D4/6=D6/8=D8/10=D10/12=D12/20=D20
|
|
25
|
+
y:ダイス数(省略:1)
|
|
26
|
+
z:難易度
|
|
27
|
+
|
|
28
|
+
・観測ロール
|
|
29
|
+
[現実乖離]の段階に応じたダイスを指定数ダイスロールして、最も高い出目を出力します。
|
|
30
|
+
KR(x)
|
|
31
|
+
x=[現実乖離]の段階(1=D4/2=D6/3=D8/4=D10/5=D12/6=D20)
|
|
32
|
+
|
|
33
|
+
KR(x,y) 観測ロール(リアリティラインあり)
|
|
34
|
+
x=[現実乖離]の段階(1=D4/2=D6/3=D8/4=D10/5=D12/6=D20)
|
|
35
|
+
y=[リアリティライン]のレベル(3=1個/2=2個/1=3個)
|
|
36
|
+
|
|
37
|
+
・虚構の収束の侵蝕度減少ロール
|
|
38
|
+
[現実乖離]の段階に応じたダイスを指定数ダイスロールして、その合計を出力します。
|
|
39
|
+
KRS(x,y)
|
|
40
|
+
x=[現実乖離]の段階(1=D4/2=D6/3=D8/4=D10/5=D12/6=D20)
|
|
41
|
+
y=ダイスの個数
|
|
42
|
+
MESSAGETEXT
|
|
43
|
+
|
|
44
|
+
register_prefix('KS', 'KR', 'KRS')
|
|
45
|
+
|
|
46
|
+
def eval_game_system_specific_command(command)
|
|
47
|
+
roll_check(command) || roll_kansoku(command) || roll_shusoku(command)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
DICE_SIZE_TO_SIDES = {
|
|
53
|
+
1 => 4,
|
|
54
|
+
2 => 4,
|
|
55
|
+
3 => 4,
|
|
56
|
+
4 => 4,
|
|
57
|
+
6 => 6,
|
|
58
|
+
8 => 8,
|
|
59
|
+
10 => 10,
|
|
60
|
+
12 => 12,
|
|
61
|
+
20 => 20,
|
|
62
|
+
}.freeze
|
|
63
|
+
|
|
64
|
+
def roll_check(command)
|
|
65
|
+
m = /^KS(?:\((\d+),([-+\d]+)?\)|(\d+))(?:>=([-+\d]+))?$/.match(command)
|
|
66
|
+
return nil unless m
|
|
67
|
+
|
|
68
|
+
dice_size = m[1]&.to_i || m[3].to_i
|
|
69
|
+
times = m[2] ? Arithmetic.eval(m[2], @round_type) : 1
|
|
70
|
+
target = m[4] && Arithmetic.eval(m[4], @round_type)
|
|
71
|
+
|
|
72
|
+
sides = DICE_SIZE_TO_SIDES[dice_size]
|
|
73
|
+
|
|
74
|
+
return nil if sides.nil? || times.nil?
|
|
75
|
+
|
|
76
|
+
dice_list = @randomizer.roll_barabara(times, sides).sort
|
|
77
|
+
value = dice_list.max.clamp(1, dice_size)
|
|
78
|
+
|
|
79
|
+
result =
|
|
80
|
+
if value == 1
|
|
81
|
+
Result.fumble("ファンブル")
|
|
82
|
+
elsif target && value < target
|
|
83
|
+
Result.failure("失敗")
|
|
84
|
+
elsif target && value == sides
|
|
85
|
+
Result.critical("クリティカル")
|
|
86
|
+
elsif target && value >= target
|
|
87
|
+
Result.success("成功")
|
|
88
|
+
else
|
|
89
|
+
Result.new()
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
result.text = [
|
|
93
|
+
target ? "(KS(#{dice_size},#{times})>=#{target})" : "(KS(#{dice_size},#{times}))",
|
|
94
|
+
("#{value}[#{dice_list.join(',')}]" if times > 1),
|
|
95
|
+
value,
|
|
96
|
+
result.text,
|
|
97
|
+
].compact.join(" > ")
|
|
98
|
+
|
|
99
|
+
return result
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
GENJITU_KAIRI_TO_SIDES = [4, 6, 8, 10, 12, 20].freeze
|
|
103
|
+
REALITY_LINE_TO_TIMES = {
|
|
104
|
+
3 => 1,
|
|
105
|
+
2 => 2,
|
|
106
|
+
1 => 3,
|
|
107
|
+
}.freeze
|
|
108
|
+
|
|
109
|
+
def roll_kansoku(command)
|
|
110
|
+
m = /^KR(?:(\d+)|\((\d),(\d)\))$/.match(command)
|
|
111
|
+
return nil unless m
|
|
112
|
+
|
|
113
|
+
dice_size = m[1]&.to_i || m[2].to_i
|
|
114
|
+
reality_line = m[3]&.to_i
|
|
115
|
+
|
|
116
|
+
if reality_line && (reality_line > 3 || reality_line < 1)
|
|
117
|
+
return nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
sides = GENJITU_KAIRI_TO_SIDES[dice_size - 1]
|
|
121
|
+
times = REALITY_LINE_TO_TIMES[reality_line] || 1
|
|
122
|
+
|
|
123
|
+
return nil unless sides
|
|
124
|
+
|
|
125
|
+
dice_list = @randomizer.roll_barabara(times, sides).sort
|
|
126
|
+
value = dice_list.max
|
|
127
|
+
|
|
128
|
+
cmd = reality_line ? "KR(#{dice_size},#{reality_line})" : "KR(#{dice_size})"
|
|
129
|
+
|
|
130
|
+
if times == 1
|
|
131
|
+
"(#{cmd}) > #{value}"
|
|
132
|
+
else
|
|
133
|
+
"(#{cmd}) > #{value}[#{dice_list.join(',')}] > #{value}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def roll_shusoku(command)
|
|
138
|
+
m = /^KRS(?:\((\d),([-+\d]+)\))$/.match(command)
|
|
139
|
+
return nil unless m
|
|
140
|
+
|
|
141
|
+
dice_size = m[1].to_i
|
|
142
|
+
times = m[2] && Arithmetic.eval(m[2], @round_type)
|
|
143
|
+
|
|
144
|
+
sides = GENJITU_KAIRI_TO_SIDES[dice_size - 1]
|
|
145
|
+
return nil if sides.nil? || times.nil?
|
|
146
|
+
|
|
147
|
+
dice_list = @randomizer.roll_barabara(times, sides)
|
|
148
|
+
value = dice_list.sum
|
|
149
|
+
|
|
150
|
+
if times == 1
|
|
151
|
+
"(KRS(#{dice_size},#{times})) > #{value}"
|
|
152
|
+
else
|
|
153
|
+
"(KRS(#{dice_size},#{times})) > #{value}[#{dice_list.join(',')}] > #{value}"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class Liminal < Base
|
|
6
|
+
# ゲームシステムの識別子
|
|
7
|
+
ID = 'Liminal'
|
|
8
|
+
|
|
9
|
+
# ゲームシステム名
|
|
10
|
+
NAME = 'リミナル'
|
|
11
|
+
|
|
12
|
+
# ゲームシステム名の読みがな
|
|
13
|
+
SORT_KEY = 'りみなる'
|
|
14
|
+
|
|
15
|
+
# ダイスボットの使い方
|
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGETEXT
|
|
17
|
+
■技能判定 LMx+b>=t+m x:技能レベル b:ボーナス t:難易度 m:敵の技能レベル(対抗判定)
|
|
18
|
+
|
|
19
|
+
例)LM2>=8: 技能レベル2,難易度8で技能判定し、その結果を表示。(クリティカル成功も表示)
|
|
20
|
+
LM3+2>=9:技能レベル3,ボーナス+2,難易度9で技能判定し、その結果を表示。( 〃 )
|
|
21
|
+
LM0>=8: 技能なし,難易度8で技能判定する。(難易度+2は自動的に足されます)
|
|
22
|
+
|
|
23
|
+
■イニシアティヴ判定 LIx+b>=t+m x:認識力レベル b:ボーナス t:難易度 m:敵の認識力レベル
|
|
24
|
+
例)LI2>=8+2: 認識力レベル2,難易度8,敵認識力レベル2で技能判定し、その結果を表示。
|
|
25
|
+
LI0>=8+2: 認識力なし,難易度8,敵認識力レベル2で技能判定する。(難易度加算なし)
|
|
26
|
+
INFO_MESSAGETEXT
|
|
27
|
+
|
|
28
|
+
register_prefix("LI", "LM")
|
|
29
|
+
|
|
30
|
+
def eval_game_system_specific_command(command)
|
|
31
|
+
resolute_action(command) || resolute_initiative(command)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# 技能判定
|
|
37
|
+
# @param [String] command
|
|
38
|
+
# @return [Result]
|
|
39
|
+
def resolute_action(command)
|
|
40
|
+
parser = Command::Parser.new("LM", round_type: @round_type)
|
|
41
|
+
.has_suffix_number
|
|
42
|
+
.restrict_cmp_op_to(:>=)
|
|
43
|
+
parsed = parser.parse(command)
|
|
44
|
+
return nil unless parsed
|
|
45
|
+
|
|
46
|
+
skill_level = parsed.suffix_number
|
|
47
|
+
bonus = parsed.modify_number
|
|
48
|
+
difficulty = parsed.target_number
|
|
49
|
+
|
|
50
|
+
dice = @randomizer.roll_barabara(2, 6)
|
|
51
|
+
dice_total = dice.sum
|
|
52
|
+
total = dice_total + skill_level + bonus
|
|
53
|
+
difficulty += 2 if skill_level == 0
|
|
54
|
+
|
|
55
|
+
return Result.new.tap do |result|
|
|
56
|
+
result.condition = (total >= difficulty)
|
|
57
|
+
result.critical = (total >= difficulty + 5)
|
|
58
|
+
if dice_total == 2
|
|
59
|
+
result.fumble = true
|
|
60
|
+
result.critical = false
|
|
61
|
+
result.condition = false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
sequence = [
|
|
65
|
+
"(LM#{skill_level}#{with_symbol(bonus)}>=#{difficulty})",
|
|
66
|
+
"#{dice_total}[#{dice.join(',')}]#{with_symbol(skill_level + bonus)}",
|
|
67
|
+
total.to_s,
|
|
68
|
+
if result.fumble?
|
|
69
|
+
"1ゾロ"
|
|
70
|
+
elsif result.critical?
|
|
71
|
+
"クリティカル"
|
|
72
|
+
else
|
|
73
|
+
result.success? ? "成功" : "失敗"
|
|
74
|
+
end
|
|
75
|
+
].compact
|
|
76
|
+
|
|
77
|
+
result.text = sequence.join(" > ")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def with_symbol(number)
|
|
82
|
+
if number == 0
|
|
83
|
+
return "+0"
|
|
84
|
+
elsif number > 0
|
|
85
|
+
return "+#{number}"
|
|
86
|
+
else
|
|
87
|
+
return number.to_s
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# イニシアティヴ判定
|
|
92
|
+
# @param [String] command
|
|
93
|
+
# @return [Result]
|
|
94
|
+
def resolute_initiative(command)
|
|
95
|
+
parser = Command::Parser.new("LI", round_type: @round_type)
|
|
96
|
+
.has_suffix_number
|
|
97
|
+
.restrict_cmp_op_to(:>=)
|
|
98
|
+
parsed = parser.parse(command)
|
|
99
|
+
return nil unless parsed
|
|
100
|
+
|
|
101
|
+
skill_level = parsed.suffix_number
|
|
102
|
+
bonus = parsed.modify_number
|
|
103
|
+
difficulty = parsed.target_number
|
|
104
|
+
|
|
105
|
+
dice = @randomizer.roll_barabara(2, 6)
|
|
106
|
+
dice_total = dice.sum
|
|
107
|
+
total = dice_total + skill_level + bonus
|
|
108
|
+
|
|
109
|
+
return Result.new.tap do |result|
|
|
110
|
+
result.condition = (total >= difficulty)
|
|
111
|
+
result.critical = (total >= difficulty + 5)
|
|
112
|
+
if dice_total == 2
|
|
113
|
+
result.fumble = true
|
|
114
|
+
result.critical = false
|
|
115
|
+
result.condition = false
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
sequence = [
|
|
119
|
+
"(LI#{skill_level}#{with_symbol(bonus)}>=#{difficulty})",
|
|
120
|
+
"#{dice_total}[#{dice.join(',')}]#{with_symbol(skill_level + bonus)}",
|
|
121
|
+
total.to_s,
|
|
122
|
+
if result.fumble?
|
|
123
|
+
"1ゾロ"
|
|
124
|
+
elsif result.critical?
|
|
125
|
+
"クリティカル"
|
|
126
|
+
else
|
|
127
|
+
result.success? ? "成功" : "失敗"
|
|
128
|
+
end
|
|
129
|
+
].compact
|
|
130
|
+
|
|
131
|
+
result.text = sequence.join(" > ")
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -151,7 +151,7 @@ module BCDice
|
|
|
151
151
|
'D' => [{'LW' => 2}, {'MW' => 26}, {'HW' => 46}, {'MO' => 76}, {'K' => 96}],
|
|
152
152
|
'E' => [{'LW' => 2}, {'MW' => 26}, {'HW' => 39}, {'MO' => 54}, {'K' => 76}],
|
|
153
153
|
'F' => [{'LW' => 2}, {'MW' => 16}, {'HW' => 39}, {'MO' => 54}, {'K' => 66}],
|
|
154
|
-
'G' => [{'LW' => 2}, {'MW' =>
|
|
154
|
+
'G' => [{'LW' => 2}, {'MW' => 6}, {'HW' => 16}, {'MO' => 26}, {'K' => 39}],
|
|
155
155
|
'M' => [{'0' => 2}, {'1' => 22}, {'2' => 42}, {'3' => 62}, {'4' => 82}, {'5' => 92}, {'6' => 102}, {'8' => 112}],
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class NRR < Base
|
|
6
|
+
# ゲームシステムの識別子
|
|
7
|
+
ID = 'NRR'
|
|
8
|
+
|
|
9
|
+
# ゲームシステム名
|
|
10
|
+
NAME = 'nRR'
|
|
11
|
+
|
|
12
|
+
# ゲームシステム名の読みがな
|
|
13
|
+
SORT_KEY = 'えぬああるあある'
|
|
14
|
+
|
|
15
|
+
# ダイスボットの使い方
|
|
16
|
+
HELP_MESSAGE = <<~INFO_MESSAGETEXT
|
|
17
|
+
▪️判定
|
|
18
|
+
・ノーマルダイス NR8
|
|
19
|
+
・有利ダイス NR10
|
|
20
|
+
・不利ダイス NR6
|
|
21
|
+
・Exダイス NR12
|
|
22
|
+
|
|
23
|
+
ダイスの個数を指定しての判定ができます。
|
|
24
|
+
例:有利ダイス2個で判定 2NR10
|
|
25
|
+
|
|
26
|
+
▪️判定結果とシンボル
|
|
27
|
+
⭕:成功
|
|
28
|
+
❌:失敗
|
|
29
|
+
✨:クリティカル(大成功)
|
|
30
|
+
💀:ファンブル(大失敗)
|
|
31
|
+
🌈:ミラクル(奇跡)
|
|
32
|
+
INFO_MESSAGETEXT
|
|
33
|
+
|
|
34
|
+
register_prefix('\d*NR(6|8|10|12)')
|
|
35
|
+
|
|
36
|
+
def initialize(command)
|
|
37
|
+
super(command)
|
|
38
|
+
|
|
39
|
+
@sort_barabara_dice = true # バラバラロール(Bコマンド)でソート有
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def eval_game_system_specific_command(command)
|
|
43
|
+
roll_nr(command)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def roll_nr(command)
|
|
49
|
+
m = /^(\d+)?NR(6|8|10|12)$/.match(command)
|
|
50
|
+
return nil unless m
|
|
51
|
+
|
|
52
|
+
times = m[1]&.to_i || 1
|
|
53
|
+
table = case m[2]
|
|
54
|
+
when "6"
|
|
55
|
+
DISADVANTAGE
|
|
56
|
+
when "8"
|
|
57
|
+
NORMAL
|
|
58
|
+
when "10"
|
|
59
|
+
ADVANTAGE
|
|
60
|
+
else
|
|
61
|
+
EXTRA
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
values = @randomizer.roll_barabara(times, table.size)
|
|
65
|
+
result = Result.new
|
|
66
|
+
text =
|
|
67
|
+
if times == 1
|
|
68
|
+
level = table[values[0] - 1]
|
|
69
|
+
result.condition = SUCCESSES.include?(level)
|
|
70
|
+
result.fumble = level == :fumble
|
|
71
|
+
result.critical = CRITICALS.include?(level)
|
|
72
|
+
|
|
73
|
+
"#{ICON[level]} #{RESULT_LABEL[level]}"
|
|
74
|
+
else
|
|
75
|
+
levels = values.map { |v| table[v - 1] }
|
|
76
|
+
values_count = levels
|
|
77
|
+
.group_by(&:itself)
|
|
78
|
+
.transform_values(&:length)
|
|
79
|
+
|
|
80
|
+
values_count_strs = LEVELS.map do |l|
|
|
81
|
+
count = values_count.fetch(l, 0)
|
|
82
|
+
next nil if count == 0
|
|
83
|
+
|
|
84
|
+
"#{ICON[l]} #{count}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
values_count_strs.compact.join(", ")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
times_str = times == 1 ? nil : times
|
|
91
|
+
result.text = "(#{times_str}NR#{m[2]}) > #{values.join(',')} > #{text}"
|
|
92
|
+
|
|
93
|
+
result
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
LEVELS = [:fumble, :failure, :success, :critical, :miracle].freeze
|
|
97
|
+
SUCCESSES = [:success, :critical, :miracle].freeze
|
|
98
|
+
CRITICALS = [:critical, :miracle].freeze
|
|
99
|
+
|
|
100
|
+
DISADVANTAGE = [:fumble, :fumble, :failure, :failure, :success, :success].freeze
|
|
101
|
+
NORMAL = [:fumble, :failure, :failure, :failure, :success, :success, :success, :critical].freeze
|
|
102
|
+
ADVANTAGE = [:fumble, :failure, :failure, :success, :success, :success, :success, :success, :critical, :critical].freeze
|
|
103
|
+
EXTRA = [:fumble, :fumble, :fumble, :failure, :success, :success, :critical, :critical, :critical, :critical, :miracle, :miracle].freeze
|
|
104
|
+
|
|
105
|
+
ICON = {
|
|
106
|
+
fumble: "💀",
|
|
107
|
+
failure: "❌",
|
|
108
|
+
success: "⭕️",
|
|
109
|
+
critical: "✨",
|
|
110
|
+
miracle: "🌈",
|
|
111
|
+
}.freeze
|
|
112
|
+
|
|
113
|
+
RESULT_LABEL = {
|
|
114
|
+
fumble: "ファンブル(大失敗)",
|
|
115
|
+
failure: "失敗",
|
|
116
|
+
success: "成功",
|
|
117
|
+
critical: "クリティカル(大成功)",
|
|
118
|
+
miracle: "ミラクル(奇跡)",
|
|
119
|
+
}.freeze
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|