bcdice 3.13.0 → 3.15.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 +104 -0
- data/i18n/Arianrhod/ko_kr.yml +3 -0
- data/i18n/Cthulhu/en_us.yml +11 -0
- data/i18n/Cthulhu/zh_hant.yml +1 -1
- data/i18n/CyberpunkRed/ja_jp.yml +389 -0
- data/i18n/CyberpunkRed/ko_kr.yml +389 -0
- data/i18n/DoubleCross/ja_jp.yml +53 -0
- data/i18n/DoubleCross/ko_kr.yml +52 -0
- data/i18n/FinalFantasyXIV/en_us.yml +4 -0
- data/i18n/FinalFantasyXIV/ja_jp.yml +4 -0
- data/i18n/FutariSousa/ja_jp.yml +284 -127
- data/i18n/KillDeathBusiness/ja_jp.yml +198 -0
- data/i18n/KizunaBullet/ja_jp.yml +653 -0
- data/i18n/MagicaLogia/ko_kr.yml +2 -2
- data/i18n/MonotoneMuseum/ja_jp.yml +246 -14
- data/i18n/MonotoneMuseum/ko_kr.yml +227 -0
- data/i18n/SkynautsBouken/ja_jp.yml +114 -0
- data/i18n/SkynautsBouken/ko_kr.yml +114 -0
- data/i18n/StratoShout/ko_kr.yml +102 -102
- data/i18n/TensaiGunshiNiNaro/ja_jp.yml +126 -0
- data/i18n/UnsungDuet/ja_jp.yml +62 -0
- data/i18n/UnsungDuet/ko_kr.yml +62 -0
- data/i18n/en_us.yml +5 -0
- data/i18n/zh_hant.yml +5 -0
- data/lib/bcdice/dice_table/range_table.rb +24 -0
- data/lib/bcdice/game_system/Agnostos.rb +248 -0
- data/lib/bcdice/game_system/Aionia.rb +131 -0
- data/lib/bcdice/game_system/AniMalus.rb +99 -59
- data/lib/bcdice/game_system/Arianrhod_Korean.rb +32 -0
- data/lib/bcdice/game_system/ArknightsFan.rb +245 -87
- data/lib/bcdice/game_system/BlackJacket.rb +244 -0
- data/lib/bcdice/game_system/BlackJacket_Korean.rb +244 -0
- data/lib/bcdice/game_system/CharonSanctions.rb +112 -0
- data/lib/bcdice/game_system/ConvictorDrive.rb +5 -4
- data/lib/bcdice/game_system/Cthulhu7th.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/full_auto.rb +293 -0
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/rollable.rb +43 -0
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +470 -306
- data/lib/bcdice/game_system/Cthulhu_English.rb +59 -0
- data/lib/bcdice/game_system/CyberpunkRed.rb +15 -6
- data/lib/bcdice/game_system/CyberpunkRed_Korean.rb +66 -0
- data/lib/bcdice/game_system/DivineCharger.rb +841 -0
- data/lib/bcdice/game_system/DoubleCross.rb +18 -1
- data/lib/bcdice/game_system/DoubleCross_Korean.rb +5 -1
- data/lib/bcdice/game_system/FinalFantasyXIV.rb +115 -0
- data/lib/bcdice/game_system/FinalFantasyXIV_English.rb +39 -0
- data/lib/bcdice/game_system/FullFace.rb +63 -12
- data/lib/bcdice/game_system/FutariSousa.rb +105 -13
- data/lib/bcdice/game_system/Garactier.rb +479 -0
- data/lib/bcdice/game_system/GardenOrder.rb +390 -9
- data/lib/bcdice/game_system/GundogRevised.rb +8 -8
- data/lib/bcdice/game_system/Insane_Korean.rb +1 -1
- data/lib/bcdice/game_system/InvisibleLiar.rb +79 -0
- data/lib/bcdice/game_system/KillDeathBusiness.rb +155 -3
- data/lib/bcdice/game_system/KimitoYell.rb +568 -0
- data/lib/bcdice/game_system/KizunaBullet.rb +240 -0
- data/lib/bcdice/game_system/KyokoShinshoku.rb +51 -8
- data/lib/bcdice/game_system/Magius.rb +125 -0
- data/lib/bcdice/game_system/Magius_3rdNewTokyoCity.rb +62 -0
- data/lib/bcdice/game_system/MonotoneMuseum.rb +14 -1
- data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
- data/lib/bcdice/game_system/NRR.rb +2 -2
- data/lib/bcdice/game_system/NSSQ.rb +17 -9
- data/lib/bcdice/game_system/NervWhitePaper.rb +129 -0
- data/lib/bcdice/game_system/RogueLikeHalf.rb +198 -0
- data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +16 -13
- data/lib/bcdice/game_system/ShinobiGami.rb +73 -43
- data/lib/bcdice/game_system/ShuumatsuBargainWars.rb +203 -0
- data/lib/bcdice/game_system/SkynautsBouken.rb +49 -134
- data/lib/bcdice/game_system/SkynautsBouken_Korean.rb +57 -0
- data/lib/bcdice/game_system/StratoShout_Korean.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +5 -1
- data/lib/bcdice/game_system/SwordWorld2_5.rb +3 -2
- data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +262 -0
- data/lib/bcdice/game_system/TheIndieHack.rb +82 -0
- data/lib/bcdice/game_system/TheOneRing2nd.rb +406 -0
- data/lib/bcdice/game_system/TheUnofficialHollowKnightRPG.rb +185 -0
- data/lib/bcdice/game_system/TorgEternity.rb +35 -6
- data/lib/bcdice/game_system/TrailOfCthulhu.rb +139 -0
- data/lib/bcdice/game_system/UnsungDuet.rb +17 -75
- data/lib/bcdice/game_system/UnsungDuet_Korean.rb +41 -0
- data/lib/bcdice/game_system/Utakaze.rb +55 -2
- data/lib/bcdice/game_system/Warhammer4.rb +124 -3
- data/lib/bcdice/game_system/WoW.rb +161 -0
- data/lib/bcdice/game_system/YankeeMustDie.rb +192 -0
- data/lib/bcdice/game_system/YearZeroEngine.rb +225 -28
- data/lib/bcdice/game_system/Yotabana.rb +62 -0
- data/lib/bcdice/game_system/YuMyoKishi.rb +141 -0
- data/lib/bcdice/game_system/cyberpunk_red/tables.rb +111 -473
- data/lib/bcdice/game_system/kizuna_bullet/tables.rb +171 -0
- data/lib/bcdice/game_system/sword_world/rating_lexer.rb +1 -0
- data/lib/bcdice/game_system/sword_world/rating_options.rb +4 -1
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +5 -0
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +129 -115
- data/lib/bcdice/game_system.rb +31 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +50 -6
@@ -0,0 +1,293 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Cthulhu7th_ChineseTraditional < Base
|
6
|
+
class FullAuto
|
7
|
+
BONUS_DICE_RANGE = (-2..2).freeze
|
8
|
+
|
9
|
+
# 停止連射的條件(難度閾值)
|
10
|
+
# @return [Hash<String, Integer>]
|
11
|
+
#
|
12
|
+
# 成功類型的小寫表記 => 難度的閾值
|
13
|
+
ROLL_FULL_AUTO_DIFFICULTY_THRESHOLD = {
|
14
|
+
# 一般
|
15
|
+
"r" => 0,
|
16
|
+
# 困難
|
17
|
+
"h" => 1,
|
18
|
+
# 極限
|
19
|
+
"e" => 2
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
def self.eval(command, randomizer)
|
23
|
+
new.eval(command, randomizer)
|
24
|
+
end
|
25
|
+
|
26
|
+
def eval(command, randomizer)
|
27
|
+
@randomizer = randomizer
|
28
|
+
get_full_auto_result(command)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
include Rollable
|
34
|
+
|
35
|
+
def get_full_auto_result(command)
|
36
|
+
m = /^FAR\((-?\d+),(-?\d+),(-?\d+)(?:,(-?\d+)?)?(?:,(-?\w+)?)?(?:,(-?\d+)?)?\)$/i.match(command)
|
37
|
+
unless m
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
bullet_count = m[1].to_i
|
42
|
+
diff = m[2].to_i
|
43
|
+
broken_number = m[3].to_i
|
44
|
+
bonus_dice_count = m[4].to_i
|
45
|
+
stop_count = m[5]&.downcase || ""
|
46
|
+
bullet_set_count_cap = m[6]&.to_i || diff / 10
|
47
|
+
|
48
|
+
output = ""
|
49
|
+
|
50
|
+
# 最大(8次 * (PC技能值最大值 / 10))= 72發,因此設置上限
|
51
|
+
bullet_count_limit = 100
|
52
|
+
if bullet_count > bullet_count_limit
|
53
|
+
output += "彈藥數量過多。將裝填的彈藥數量更改為#{bullet_count_limit}發。\n"
|
54
|
+
bullet_count = bullet_count_limit
|
55
|
+
end
|
56
|
+
|
57
|
+
# 如果設置的連射上限不合理則顯示注意
|
58
|
+
if (bullet_set_count_cap > diff / 10) && (diff > 39) && !m[6].nil?
|
59
|
+
bullet_set_count_cap = diff / 10
|
60
|
+
output += "連射的彈藥數量上限為\[技能值÷10(取整)\]發,因此無法指定更高的數量。連射的彈藥數量更改為#{bullet_set_count_cap}發。\n"
|
61
|
+
elsif (diff <= 39) && (bullet_set_count_cap > 3) && !m[6].nil?
|
62
|
+
bullet_set_count_cap = 3
|
63
|
+
output += "技能值在39以下時,連射的彈藥數量上限和下限均為3發。連射的彈藥數量更改為#{bullet_set_count_cap}發。\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
# 如果設置的連射下限不合理則顯示注意或錯誤
|
67
|
+
return "連射的彈藥數量必須為正數。" if (bullet_set_count_cap <= 0) && !m[6].nil?
|
68
|
+
|
69
|
+
if (bullet_set_count_cap < 3) && !m[6].nil?
|
70
|
+
bullet_set_count_cap = 3
|
71
|
+
output += "連射的彈藥數量下限為3發。連射的彈藥數量更改為3發。\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
return "彈藥數量必須為正數。" if bullet_count <= 0
|
75
|
+
return "目標值必須為正數。" if diff <= 0
|
76
|
+
|
77
|
+
if broken_number < 0
|
78
|
+
output += "故障值必須為正數。去掉負號。\n"
|
79
|
+
broken_number = broken_number.abs
|
80
|
+
end
|
81
|
+
|
82
|
+
unless BONUS_DICE_RANGE.include?(bonus_dice_count)
|
83
|
+
return "錯誤。獎勵・懲罰骰的值必須在#{BONUS_DICE_RANGE.min}~#{BONUS_DICE_RANGE.max}之間。"
|
84
|
+
end
|
85
|
+
|
86
|
+
output += "獎勵・懲罰骰[#{bonus_dice_count}]"
|
87
|
+
output += roll_full_auto(bullet_count, diff, broken_number, bonus_dice_count, stop_count, bullet_set_count_cap)
|
88
|
+
|
89
|
+
return output
|
90
|
+
end
|
91
|
+
|
92
|
+
def roll_full_auto(bullet_count, diff, broken_number, dice_num, stop_count, bullet_set_count_cap)
|
93
|
+
output = ""
|
94
|
+
loop_count = 0
|
95
|
+
|
96
|
+
counts = {
|
97
|
+
hit_bullet: 0,
|
98
|
+
impale_bullet: 0,
|
99
|
+
bullet: bullet_count,
|
100
|
+
}
|
101
|
+
|
102
|
+
# 難度變更用循環
|
103
|
+
4.times do |more_difficulty|
|
104
|
+
output += get_next_difficulty_message(more_difficulty)
|
105
|
+
|
106
|
+
# 隨著懲罰骰的減少進行擲骰循環
|
107
|
+
while dice_num >= BONUS_DICE_RANGE.min
|
108
|
+
loop_count += 1
|
109
|
+
hit_result, total, total_list = get_hit_result_infos(dice_num, diff, more_difficulty)
|
110
|
+
output += "\n#{loop_count}次: > #{total_list.join(', ')} > #{hit_result}"
|
111
|
+
|
112
|
+
if total >= broken_number
|
113
|
+
output += " 卡彈"
|
114
|
+
return get_hit_result_text(output, counts)
|
115
|
+
end
|
116
|
+
|
117
|
+
hit_type = get_hit_type(more_difficulty, hit_result)
|
118
|
+
hit_bullet, impale_bullet, lost_bullet = get_bullet_results(counts[:bullet], hit_type, diff, bullet_set_count_cap)
|
119
|
+
|
120
|
+
output += " (#{hit_bullet}發命中,#{impale_bullet}發貫穿)"
|
121
|
+
|
122
|
+
counts[:hit_bullet] += hit_bullet
|
123
|
+
counts[:impale_bullet] += impale_bullet
|
124
|
+
counts[:bullet] -= lost_bullet
|
125
|
+
|
126
|
+
return get_hit_result_text(output, counts) if counts[:bullet] <= 0
|
127
|
+
|
128
|
+
dice_num -= 1
|
129
|
+
end
|
130
|
+
|
131
|
+
# 當達到指定的難度時,停止連射處理
|
132
|
+
if should_stop_roll_full_auto?(stop_count, more_difficulty)
|
133
|
+
output += "\n【因達到指定難度,處理結束。】"
|
134
|
+
break
|
135
|
+
end
|
136
|
+
|
137
|
+
dice_num += 1
|
138
|
+
end
|
139
|
+
|
140
|
+
return get_hit_result_text(output, counts)
|
141
|
+
end
|
142
|
+
|
143
|
+
# 判斷是否應該停止連射處理
|
144
|
+
# @param [String] stop_count 成功的類型
|
145
|
+
# @param [Integer] difficulty 難度
|
146
|
+
# @return [Boolean]
|
147
|
+
def should_stop_roll_full_auto?(stop_count, difficulty)
|
148
|
+
difficulty_threshold = ROLL_FULL_AUTO_DIFFICULTY_THRESHOLD[stop_count]
|
149
|
+
return difficulty_threshold && difficulty >= difficulty_threshold
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_hit_result_infos(dice_num, diff, more_difficulty)
|
153
|
+
total, total_list = roll_with_bonus(dice_num)
|
154
|
+
|
155
|
+
fumbleable = get_fumbleable(more_difficulty)
|
156
|
+
hit_result = ResultLevel.from_values(total, diff, fumbleable).to_s
|
157
|
+
|
158
|
+
return hit_result, total, total_list
|
159
|
+
end
|
160
|
+
|
161
|
+
def get_hit_result_text(output, counts)
|
162
|
+
return "#{output}\n> #{counts[:hit_bullet]}發一般命中,#{counts[:impale_bullet]}發貫穿,剩餘彈藥#{counts[:bullet]}發"
|
163
|
+
end
|
164
|
+
|
165
|
+
def get_hit_type(more_difficulty, hit_result)
|
166
|
+
success_list, impale_bullet_list = get_success_list_impale_bullet_list(more_difficulty)
|
167
|
+
|
168
|
+
return :hit if success_list.include?(hit_result)
|
169
|
+
return :impale if impale_bullet_list.include?(hit_result)
|
170
|
+
|
171
|
+
return ""
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_bullet_results(bullet_count, hit_type, diff, bullet_set_count_cap)
|
175
|
+
bullet_set_count = get_set_of_bullet(diff, bullet_set_count_cap)
|
176
|
+
hit_bullet_count_base = get_hit_bullet_count_base(diff, bullet_set_count)
|
177
|
+
impale_bullet_count_base = (bullet_set_count / 2.to_f)
|
178
|
+
|
179
|
+
lost_bullet_count = 0
|
180
|
+
hit_bullet_count = 0
|
181
|
+
impale_bullet_count = 0
|
182
|
+
|
183
|
+
if !last_bullet_turn?(bullet_count, bullet_set_count)
|
184
|
+
|
185
|
+
case hit_type
|
186
|
+
when :hit
|
187
|
+
hit_bullet_count = hit_bullet_count_base # 計算一般命中的彈數
|
188
|
+
|
189
|
+
when :impale
|
190
|
+
impale_bullet_count = impale_bullet_count_base.floor # 計算貫穿的彈數
|
191
|
+
hit_bullet_count = impale_bullet_count_base.ceil
|
192
|
+
end
|
193
|
+
|
194
|
+
lost_bullet_count = bullet_set_count
|
195
|
+
|
196
|
+
else
|
197
|
+
|
198
|
+
case hit_type
|
199
|
+
when :hit
|
200
|
+
hit_bullet_count = get_last_hit_bullet_count(bullet_count)
|
201
|
+
|
202
|
+
when :impale
|
203
|
+
impale_bullet_count = get_last_hit_bullet_count(bullet_count)
|
204
|
+
hit_bullet_count = bullet_count - impale_bullet_count
|
205
|
+
end
|
206
|
+
|
207
|
+
lost_bullet_count = bullet_count
|
208
|
+
end
|
209
|
+
|
210
|
+
return hit_bullet_count, impale_bullet_count, lost_bullet_count
|
211
|
+
end
|
212
|
+
|
213
|
+
def get_success_list_impale_bullet_list(more_difficulty)
|
214
|
+
success_list = []
|
215
|
+
impale_bullet_list = []
|
216
|
+
|
217
|
+
case more_difficulty
|
218
|
+
when 0
|
219
|
+
success_list = ["困難成功", "一般成功"]
|
220
|
+
impale_bullet_list = ["大成功", "極限成功"]
|
221
|
+
when 1
|
222
|
+
success_list = ["困難成功"]
|
223
|
+
impale_bullet_list = ["大成功", "極限成功"]
|
224
|
+
when 2
|
225
|
+
success_list = []
|
226
|
+
impale_bullet_list = ["大成功", "極限成功"]
|
227
|
+
when 3
|
228
|
+
success_list = ["大成功"]
|
229
|
+
impale_bullet_list = []
|
230
|
+
end
|
231
|
+
|
232
|
+
return success_list, impale_bullet_list
|
233
|
+
end
|
234
|
+
|
235
|
+
def get_next_difficulty_message(more_difficulty)
|
236
|
+
case more_difficulty
|
237
|
+
when 1
|
238
|
+
return "\n【難度已更改為困難】"
|
239
|
+
when 2
|
240
|
+
return "\n【難度已更改為極限】"
|
241
|
+
when 3
|
242
|
+
return "\n【難度已更改為大成功】"
|
243
|
+
end
|
244
|
+
|
245
|
+
return ""
|
246
|
+
end
|
247
|
+
|
248
|
+
def get_set_of_bullet(diff, bullet_set_count_cap)
|
249
|
+
bullet_set_count = diff / 10
|
250
|
+
|
251
|
+
if bullet_set_count_cap < bullet_set_count
|
252
|
+
bullet_set_count = bullet_set_count_cap
|
253
|
+
end
|
254
|
+
|
255
|
+
if (diff >= 1) && (diff < 30)
|
256
|
+
bullet_set_count = 3 # 技能值在29以下的最低值保障處理
|
257
|
+
end
|
258
|
+
|
259
|
+
return bullet_set_count
|
260
|
+
end
|
261
|
+
|
262
|
+
def get_hit_bullet_count_base(diff, bullet_set_count)
|
263
|
+
hit_bullet_count_base = (bullet_set_count / 2)
|
264
|
+
|
265
|
+
if (diff >= 1) && (diff < 30)
|
266
|
+
hit_bullet_count_base = 1 # 技能值在29以下的最低值保障
|
267
|
+
end
|
268
|
+
|
269
|
+
return hit_bullet_count_base
|
270
|
+
end
|
271
|
+
|
272
|
+
def last_bullet_turn?(bullet_count, bullet_set_count)
|
273
|
+
((bullet_count - bullet_set_count) < 0)
|
274
|
+
end
|
275
|
+
|
276
|
+
def get_last_hit_bullet_count(bullet_count)
|
277
|
+
# 剩餘1發的最低值保障處理
|
278
|
+
if bullet_count == 1
|
279
|
+
return 1
|
280
|
+
end
|
281
|
+
|
282
|
+
count = (bullet_count / 2.to_f).floor
|
283
|
+
return count
|
284
|
+
end
|
285
|
+
|
286
|
+
def get_fumbleable(more_difficulty)
|
287
|
+
# 因為成功的出目必須在49以下,因此失誤值上升
|
288
|
+
return (more_difficulty >= 1)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BCDice
|
4
|
+
module GameSystem
|
5
|
+
class Cthulhu7th_ChineseTraditional < Base
|
6
|
+
module Rollable
|
7
|
+
private
|
8
|
+
|
9
|
+
# 1D100の一の位用のダイスロール
|
10
|
+
# 0から9までの値を返す
|
11
|
+
#
|
12
|
+
# @return [Integer]
|
13
|
+
def roll_ones_d10
|
14
|
+
dice = @randomizer.roll_once(10)
|
15
|
+
return 0 if dice == 10
|
16
|
+
|
17
|
+
return dice
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param bonus [Integer] ボーナス・ペナルティダイスの数。負の数ならペナルティダイス。
|
21
|
+
# @return [Array<(Integer, Array<Integer>)>]
|
22
|
+
def roll_with_bonus(bonus)
|
23
|
+
tens_list = Array.new(bonus.abs + 1) { @randomizer.roll_tens_d10 }
|
24
|
+
ones = roll_ones_d10()
|
25
|
+
|
26
|
+
dice_list = tens_list.map do |tens|
|
27
|
+
dice = tens + ones
|
28
|
+
dice == 0 ? 100 : dice
|
29
|
+
end
|
30
|
+
|
31
|
+
dice =
|
32
|
+
if bonus >= 0
|
33
|
+
dice_list.min
|
34
|
+
else
|
35
|
+
dice_list.max
|
36
|
+
end
|
37
|
+
|
38
|
+
return dice, dice_list
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|