bcdice 3.12.0 → 3.14.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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/i18n/Arianrhod/ko_kr.yml +3 -0
  4. data/i18n/Cthulhu/en_us.yml +11 -0
  5. data/i18n/CyberpunkRed/ja_jp.yml +389 -0
  6. data/i18n/FinalFantasyXIV/en_us.yml +4 -0
  7. data/i18n/FinalFantasyXIV/ja_jp.yml +4 -0
  8. data/i18n/FutariSousa/ja_jp.yml +158 -1
  9. data/i18n/KizunaBullet/ja_jp.yml +653 -0
  10. data/i18n/MonotoneMuseum/ja_jp.yml +246 -14
  11. data/i18n/SkynautsBouken/ja_jp.yml +114 -0
  12. data/i18n/TensaiGunshiNiNaro/ja_jp.yml +126 -0
  13. data/i18n/UnsungDuet/ja_jp.yml +62 -0
  14. data/i18n/UnsungDuet/ko_kr.yml +62 -0
  15. data/i18n/en_us.yml +5 -0
  16. data/lib/bcdice/arithmetic/parser.rb +4 -2
  17. data/lib/bcdice/base.rb +1 -1
  18. data/lib/bcdice/command/parser.rb +4 -2
  19. data/lib/bcdice/common_command/add_dice/parser.rb +4 -2
  20. data/lib/bcdice/common_command/barabara_dice/parser.rb +4 -2
  21. data/lib/bcdice/common_command/calc/parser.rb +4 -2
  22. data/lib/bcdice/common_command/reroll_dice/parser.rb +4 -2
  23. data/lib/bcdice/common_command/tally_dice/parser.rb +4 -2
  24. data/lib/bcdice/common_command/upper_dice/parser.rb +4 -2
  25. data/lib/bcdice/dice_table/range_table.rb +24 -0
  26. data/lib/bcdice/game_system/Agnostos.rb +248 -0
  27. data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
  28. data/lib/bcdice/game_system/Alsetto.rb +2 -2
  29. data/lib/bcdice/game_system/AniMalus.rb +261 -0
  30. data/lib/bcdice/game_system/Arianrhod_Korean.rb +30 -0
  31. data/lib/bcdice/game_system/ArknightsFan.rb +182 -0
  32. data/lib/bcdice/game_system/Avandner.rb +1 -1
  33. data/lib/bcdice/game_system/BBN.rb +1 -1
  34. data/lib/bcdice/game_system/BadLife.rb +3 -3
  35. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  36. data/lib/bcdice/game_system/BlackJacket.rb +244 -0
  37. data/lib/bcdice/game_system/Chill3.rb +6 -6
  38. data/lib/bcdice/game_system/ConvictorDrive.rb +5 -4
  39. data/lib/bcdice/game_system/Cthulhu_English.rb +59 -0
  40. data/lib/bcdice/game_system/CyberpunkRed.rb +14 -4
  41. data/lib/bcdice/game_system/DarkSouls.rb +1 -1
  42. data/lib/bcdice/game_system/DivineCharger.rb +841 -0
  43. data/lib/bcdice/game_system/Elric.rb +1 -1
  44. data/lib/bcdice/game_system/FinalFantasyXIV.rb +115 -0
  45. data/lib/bcdice/game_system/FinalFantasyXIV_English.rb +39 -0
  46. data/lib/bcdice/game_system/FullFace.rb +121 -0
  47. data/lib/bcdice/game_system/FutariSousa.rb +88 -8
  48. data/lib/bcdice/game_system/InfiniteFantasia.rb +4 -1
  49. data/lib/bcdice/game_system/Insane_Korean.rb +1 -1
  50. data/lib/bcdice/game_system/InvisibleLiar.rb +79 -0
  51. data/lib/bcdice/game_system/Irisbane.rb +1 -1
  52. data/lib/bcdice/game_system/KillDeathBusiness.rb +1 -1
  53. data/lib/bcdice/game_system/KizunaBullet.rb +240 -0
  54. data/lib/bcdice/game_system/KyokoShinshoku.rb +201 -0
  55. data/lib/bcdice/game_system/Liminal.rb +136 -0
  56. data/lib/bcdice/game_system/MetalHead.rb +1 -1
  57. data/lib/bcdice/game_system/MetalHeadExtream.rb +1 -1
  58. data/lib/bcdice/game_system/MonotoneMuseum.rb +14 -1
  59. data/lib/bcdice/game_system/NRR.rb +122 -0
  60. data/lib/bcdice/game_system/NSSQ.rb +1 -1
  61. data/lib/bcdice/game_system/NightWizard.rb +1 -1
  62. data/lib/bcdice/game_system/NightWizard3rd.rb +15 -2
  63. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
  64. data/lib/bcdice/game_system/PastFutureParadox.rb +1238 -0
  65. data/lib/bcdice/game_system/Postman.rb +3 -3
  66. data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
  67. data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +1 -1
  68. data/lib/bcdice/game_system/Ryutama.rb +4 -4
  69. data/lib/bcdice/game_system/ShuumatsuBargainWars.rb +203 -0
  70. data/lib/bcdice/game_system/Siren.rb +97 -0
  71. data/lib/bcdice/game_system/Skynauts.rb +1 -1
  72. data/lib/bcdice/game_system/SkynautsBouken.rb +45 -130
  73. data/lib/bcdice/game_system/Strave.rb +1 -1
  74. data/lib/bcdice/game_system/SwordWorld.rb +1 -1
  75. data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +228 -0
  76. data/lib/bcdice/game_system/TheOneRing2nd.rb +406 -0
  77. data/lib/bcdice/game_system/TheUnofficialHollowKnightRPG.rb +185 -0
  78. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  79. data/lib/bcdice/game_system/TrailOfCthulhu.rb +139 -0
  80. data/lib/bcdice/game_system/TrinitySeven.rb +1 -1
  81. data/lib/bcdice/game_system/UnsungDuet.rb +17 -75
  82. data/lib/bcdice/game_system/UnsungDuet_Korean.rb +41 -0
  83. data/lib/bcdice/game_system/Utakaze.rb +55 -2
  84. data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +12 -6
  85. data/lib/bcdice/game_system/Warhammer4.rb +124 -3
  86. data/lib/bcdice/game_system/WerewolfTheApocalypse5th.rb +12 -6
  87. data/lib/bcdice/game_system/Yotabana.rb +62 -0
  88. data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +1 -1
  89. data/lib/bcdice/game_system/cyberpunk_red/tables.rb +111 -473
  90. data/lib/bcdice/game_system/kizuna_bullet/tables.rb +171 -0
  91. data/lib/bcdice/game_system/sword_world/rating_parser.rb +4 -2
  92. data/lib/bcdice/game_system.rb +24 -0
  93. data/lib/bcdice/loader.rb +1 -1
  94. data/lib/bcdice/version.rb +1 -1
  95. metadata +55 -5
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class ArknightsFan < Base
6
+ # ゲームシステムの識別子
7
+ ID = "ArknightsFan"
8
+
9
+ # ゲームシステム名
10
+ NAME = "アークナイツTRPG by Dapto"
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = "ああくないつTRPGはいたふと"
14
+
15
+ HELP_MESSAGE = <<~TEXT
16
+ ■ 判定 (nADm>=x)
17
+ nDmのダイスロールをして、x 以下であれば成功。
18
+ 出目が91以上でエラー。
19
+ 出目が10以下でクリティカル。
20
+
21
+ ■ 判定 (nABm>=x)
22
+ nBmのダイスロールをして、
23
+ x 以下であれば成功数+1。
24
+ 出目が91以上でエラー。成功数+1。
25
+ 出目が10以下でクリティカル。成功数-1。
26
+ 上記による成功数をカウント。
27
+
28
+ ■ 判定 (nABm>=x--役職)
29
+ nBmのダイスロールをして、
30
+ 出目が x 以下であれば成功数+1。
31
+ 出目が91以上でエラー。成功数+1。
32
+ 出目が10以下でクリティカル。成功数-1。
33
+ 上記による成功数をカウントした上で、以下の役職による成功数増加効果を適応。
34
+ 狙撃(SNIPER) 成功数1以上のとき、成功数+1。
35
+ TEXT
36
+
37
+ register_prefix('\d*AD\d*', '\d*AB\d*', '--ADDICTION', '--WORSENING')
38
+
39
+ def eval_game_system_specific_command(command)
40
+ roll_ad(command) || roll_ab(command) || roll_addiction(command) || roll_worsening(command)
41
+ end
42
+
43
+ private
44
+
45
+ def roll_ad(command)
46
+ m = /^(\d*)AD(\d*)<=(\d+)$/.match(command)
47
+ return nil unless m
48
+
49
+ times = m[1]
50
+ sides = m[2]
51
+ target = m[3].to_i
52
+ times = !times.empty? ? times.to_i : 1
53
+ sides = !sides.empty? ? sides.to_i : 100
54
+ return roll_d(command, times, sides, target)
55
+ end
56
+
57
+ def roll_ab(command)
58
+ m = /^(\d*)AB(\d*)<=(\d+)(?:--([^\d\s]+)(0)?)?$/.match(command)
59
+ return nil unless m
60
+
61
+ times = m[1]
62
+ sides = m[2]
63
+ target = m[3].to_i
64
+ type = m[4]
65
+ suffix = m[5]
66
+ times = !times.empty? ? times.to_i : 1
67
+ sides = !sides.empty? ? sides.to_i : 100
68
+
69
+ if suffix || type.nil?
70
+ roll_b(command, times, sides, target)
71
+ else
72
+ roll_b_withtype(command, times, sides, target, type)
73
+ end
74
+ end
75
+
76
+ def roll_d(command, times, sides, target)
77
+ dice_list = @randomizer.roll_barabara(times, sides).sort
78
+ total = dice_list.sum
79
+ success = total <= target
80
+
81
+ crierror =
82
+ if total <= 10
83
+ "Critical"
84
+ elsif total >= 91
85
+ "Error"
86
+ else
87
+ "Neutral"
88
+ end
89
+
90
+ result =
91
+ if success && (crierror == "Critical")
92
+ "クリティカル!"
93
+ elsif success && (crierror == "Neutral")
94
+ "成功"
95
+ elsif success && (crierror == "Error")
96
+ "成功"
97
+ elsif !success && (crierror == "Critical")
98
+ "失敗"
99
+ elsif !success && (crierror == "Neutral")
100
+ "失敗"
101
+ elsif !success && (crierror == "Error")
102
+ "エラー"
103
+ end
104
+
105
+ if times == 1
106
+ return "(#{command}) > #{dice_list.join(',')} > #{result}"
107
+ else
108
+ return "(#{command}) > #{total}[#{dice_list.join(',')}] > #{result}"
109
+ end
110
+ end
111
+
112
+ def roll_b(command, times, sides, target)
113
+ dice_list, success_count, critical_count, error_count = process_b(times, sides, target)
114
+ result_count = success_count + critical_count - error_count
115
+
116
+ return "(#{command}) > [#{dice_list.join(',')}] > #{success_count}+#{critical_count}C-#{error_count}E > 成功数#{result_count}"
117
+ end
118
+
119
+ def roll_b_withtype(command, times, sides, target, type)
120
+ dice_list, success_count, critical_count, error_count = process_b(times, sides, target)
121
+ result_count = success_count + critical_count - error_count
122
+
123
+ type_effect =
124
+ if (type == "SNIPER") && (result_count > 0)
125
+ 1
126
+ else
127
+ 0
128
+ end
129
+ result_count += type_effect
130
+
131
+ return "(#{command}) > [#{dice_list.join(',')}] > #{success_count}+#{critical_count}C-#{error_count}E+#{type_effect}(#{type}) > 成功数#{result_count}"
132
+ end
133
+
134
+ def process_b(times, sides, target)
135
+ dice_list = @randomizer.roll_barabara(times, sides).sort
136
+
137
+ success_count = 0
138
+ critical_count = 0
139
+ error_count = 0
140
+
141
+ dice_list.each do |value|
142
+ success_count += 1 if value <= target
143
+ critical_count += 1 if value <= 10
144
+ error_count += 1 if value >= 91
145
+ end
146
+
147
+ return [dice_list, success_count, critical_count, error_count]
148
+ end
149
+
150
+ ADDICTION_TABLE = [
151
+ "中枢神経障害",
152
+ "多臓器不全",
153
+ "急性ストレス反応",
154
+ ].freeze
155
+
156
+ def roll_addiction(command)
157
+ return nil if command != "--ADDICTION"
158
+
159
+ value = @randomizer.roll_once(3)
160
+ chosen = ADDICTION_TABLE[value - 1]
161
+
162
+ return "--ADDICTION > #{chosen}"
163
+ end
164
+
165
+ WORSENING_TABLE = [
166
+ "末梢神経障害",
167
+ "内臓機能不全",
168
+ "精神症状",
169
+ ].freeze
170
+
171
+ def roll_worsening(command)
172
+ return nil if command != "--WORSENING"
173
+
174
+ value = @randomizer.roll_once(3)
175
+ chosen = WORSENING_TABLE[value - 1]
176
+ elapse = @randomizer.roll_once(6) + 1
177
+
178
+ return "--WORSENING > #{chosen}: #{elapse} rounds"
179
+ end
180
+ end
181
+ end
182
+ end
@@ -85,7 +85,7 @@ module BCDice
85
85
  totalDamage = totalSuccessCount * damage + totalCriticalCount * criticalTrigger
86
86
 
87
87
  result += "(#{diceCount}D10\<\=#{target}) > #{text} > Hits:#{totalSuccessCount}*#{damage}"
88
- result += " + Trigger:#{totalCriticalCount}*#{criticalTrigger}" if criticalTrigger > 0
88
+ result += " + Trigger:#{totalCriticalCount}*#{criticalTrigger}" if criticalTrigger > 0
89
89
  result += " > #{totalDamage}ダメージ"
90
90
  else
91
91
  result += "(#{diceCount}D10\<\=#{target}) > #{text} > 成功数:#{totalSuccessCount}"
@@ -72,7 +72,7 @@ module BCDice
72
72
  @roll_times = m[1].to_i
73
73
  @modify_str = m[2] || ''
74
74
  @modify = m[2].to_i
75
- @difficulty = m[4] ? m[4].to_i : nil
75
+ @difficulty = m[4]&.to_i
76
76
 
77
77
  base = critical_base(@roll_times)
78
78
  @critical = base + m[7].to_i
@@ -58,7 +58,7 @@ module BCDice
58
58
  fumble = 1
59
59
 
60
60
  isStormy = (m[2] == 'GL') # 波乱万丈
61
- if isStormy
61
+ if isStormy
62
62
  critical -= 3
63
63
  fumble += 1
64
64
  end
@@ -69,7 +69,7 @@ module BCDice
69
69
  critical, fumble = get_critival_fumble(critical, fumble, m[8], m[9])
70
70
 
71
71
  target = get_value(m[11])
72
- optionalText = (m[13] || '')
72
+ optionalText = m[13] || ''
73
73
 
74
74
  return checkRoll(diceCount, modify, critical, fumble, target, isStormy, optionalText)
75
75
  end
@@ -116,7 +116,7 @@ module BCDice
116
116
 
117
117
  if isCritical
118
118
  result += "成功(クリティカル)"
119
- elsif total >= target
119
+ elsif total >= target
120
120
  result += "成功"
121
121
  else
122
122
  result += "失敗"
@@ -121,7 +121,7 @@ module BCDice
121
121
  set += 1 if diceCount > 1
122
122
  end
123
123
 
124
- if criticalCallDice != 0
124
+ if criticalCallDice != 0
125
125
  c_cnt = diceCountList[criticalCallDice - 1]
126
126
  suc = c_cnt * 2
127
127
 
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdice/dice_table/range_table'
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class BlackJacket < Base
8
+ # ゲームシステムの識別子
9
+ ID = 'BlackJacket'
10
+
11
+ # ゲームシステム名
12
+ NAME = 'ブラックジャケットRPG'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = 'ふらつくしあけつとRPG'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
19
+ ・行為判定(BJx)
20
+  x:成功率
21
+  例)BJ80
22
+  クリティカル、ファンブルの自動的判定を行います。
23
+  「BJ50+20-30」のように加減算記述も可能。
24
+  成功率は上限100%、下限0%
25
+ ・デスチャート(DCxY)
26
+  x:チャートの種類。肉体:DCL、精神:DCS、環境:DCC
27
+  Y=マイナス値
28
+  例)DCL5:ライフが -5 の判定
29
+    DCS3:サニティーが -3 の判定
30
+    DCC0:クレジット 0 の判定
31
+ ・チャレンジ・ペナルティ・チャート(CPC)
32
+ ・サイドトラック・チャート(STC)
33
+ INFO_MESSAGE_TEXT
34
+
35
+ def eval_game_system_specific_command(command)
36
+ resolute_action(command) || roll_death_chart(command) || roll_tables(command, TABLES)
37
+ end
38
+
39
+ private
40
+
41
+ def resolute_action(command)
42
+ m = /^BJ(\d+([+-]\d+)*)$/.match(command)
43
+ unless m
44
+ return nil
45
+ end
46
+
47
+ success_rate = ArithmeticEvaluator.eval(m[1])
48
+
49
+ roll_result, dice10, dice01 = roll_d100
50
+ roll_result_text = format('%02d', roll_result)
51
+
52
+ result = action_result(roll_result, dice10, dice01, success_rate)
53
+
54
+ sequence = [
55
+ "行為判定(成功率:#{success_rate}%)",
56
+ "1D100[#{dice10},#{dice01}]=#{roll_result_text}",
57
+ roll_result_text.to_s,
58
+ result.text
59
+ ]
60
+
61
+ result.text = sequence.join(" > ")
62
+ result
63
+ end
64
+
65
+ SUCCESS_STR = "成功"
66
+ FAILURE_STR = "失敗"
67
+ CRITICAL_STR = (SUCCESS_STR + " > クリティカル! パワーの代償1/2").freeze
68
+ FUMBLE_STR = (FAILURE_STR + " > ファンブル! パワーの代償2倍&振り直し不可").freeze
69
+ MISERY_STR = (FAILURE_STR + " > ミザリー! パワーの代償2倍&振り直し不可").freeze
70
+
71
+ def action_result(total, tens, ones, success_rate)
72
+ if total == 100
73
+ Result.fumble(MISERY_STR)
74
+ elsif success_rate <= 0
75
+ Result.fumble(FUMBLE_STR)
76
+ elsif total <= success_rate - 100
77
+ Result.critical(CRITICAL_STR)
78
+ elsif tens == ones
79
+ if total <= success_rate
80
+ Result.critical(CRITICAL_STR)
81
+ else
82
+ Result.fumble(FUMBLE_STR)
83
+ end
84
+ elsif total <= success_rate
85
+ Result.success(SUCCESS_STR)
86
+ else
87
+ Result.failure(FAILURE_STR)
88
+ end
89
+ end
90
+
91
+ def roll_d100
92
+ dice10 = @randomizer.roll_once(10)
93
+ dice10 = 0 if dice10 == 10
94
+ dice01 = @randomizer.roll_once(10)
95
+ dice01 = 0 if dice01 == 10
96
+
97
+ roll_result = dice10 * 10 + dice01
98
+ roll_result = 100 if roll_result == 0
99
+
100
+ return roll_result, dice10, dice01
101
+ end
102
+
103
+ class DeathChart
104
+ def initialize(name, chart)
105
+ @name = name
106
+ @chart = chart.freeze
107
+
108
+ if @chart.size != 11
109
+ raise ArgumentError, "unexpected chart size #{name.inspect} (given #{@chart.size}, expected 11)"
110
+ end
111
+ end
112
+
113
+ # @param randomizer [Randomizer]
114
+ # @param minus_score [Integer]
115
+ # @return [String]
116
+ def roll(randomizer, minus_score)
117
+ dice = randomizer.roll_once(10)
118
+ key_number = dice + minus_score
119
+
120
+ key_text, chosen = at(key_number)
121
+
122
+ return "デスチャート(#{@name})[マイナス値:#{minus_score} + 1D10(->#{dice}) = #{key_number}] > #{key_text} : #{chosen}"
123
+ end
124
+
125
+ private
126
+
127
+ # key_numberの10から20がindexの0から10に対応する
128
+ def at(key_number)
129
+ if key_number < 10
130
+ ["10以下", @chart.first]
131
+ elsif key_number > 20
132
+ ["20以上", @chart.last]
133
+ else
134
+ [key_number.to_s, @chart[key_number - 10]]
135
+ end
136
+ end
137
+ end
138
+
139
+ def roll_death_chart(command)
140
+ m = /^DC([LSC])(\d+)$/i.match(command)
141
+ unless m
142
+ return m
143
+ end
144
+
145
+ chart = DEATH_CHARTS[m[1]]
146
+ minus_score = m[2].to_i
147
+
148
+ return chart.roll(@randomizer, minus_score)
149
+ end
150
+
151
+ DEATH_CHARTS = {
152
+ 'L' => DeathChart.new(
153
+ '肉体',
154
+ [
155
+ "何も無し。キミは奇跡的に一命を取り留めた。闘いは続く。",
156
+ "激痛が走る。以後、イベント終了時まで、全ての判定の成功率-10%。",
157
+ "もう、体が動かない……。キミは[硬直2]を受ける。",
158
+ "渾身の一撃!! キミは〈生存〉判定を行なう。失敗した場合、[死亡]する。",
159
+ "突然、目の前が真っ暗になった。キミは[気絶2]を受ける。",
160
+ "以後、イベント終了時まで、全ての判定の成功率-20%。",
161
+ "記録的一撃!! キミは〈生存〉-20%の判定を行なう。失敗した場合、[死亡]する。",
162
+ "生きているのか死んでいるのか。キミは[瀕死2]を受ける。",
163
+ "叙事詩的一撃!! キミは〈生存〉-30%の判定を行なう。失敗した場合、[死亡]する。",
164
+ "以後、イベント終了時まで、全ての判定の成功率-30%。",
165
+ "神話的一撃!! キミは宙を舞って三回転ほどした後、地面に叩きつけられる。見るも無惨な姿。肉体は原型を留めていない(キミは[死亡]した)。",
166
+ ]
167
+ ),
168
+ 'S' => DeathChart.new(
169
+ '精神',
170
+ [
171
+ "何も無し。キミは歯を食いしばってストレスに耐えた。",
172
+ "以後、イベント終了時まで、全ての判定の成功率-10%。",
173
+ "云い知れぬ恐怖がキミを襲う。キミは[恐怖2]を受ける。",
174
+ "とても傷ついた。キミは〈意思〉判定を行なう。失敗した場合、[絶望]してNPCとなる。",
175
+ "キミは意識を失った。キミは[気絶2]を受ける。",
176
+ "以後、イベント終了時まで、全ての判定の成功率-20%。",
177
+ "信じる者にだまされたような痛み。キミは〈意思〉-20%の判定を行なう。失敗した場合、[絶望]してNPCとなる。",
178
+ "仲間に裏切られたのかも知れない。キミは[混乱2]を受ける。",
179
+ "あまりに残酷な現実。キミは〈意思〉-30%の判定を行なう。失敗した場合、[絶望]してNPCとなる。",
180
+ "以後、イベント終了時まで、全ての判定の成功率-30%。",
181
+ "宇宙開闢の理に触れるも、それは人類の認識限界を超える何かであった。キミは[絶望]し、以後NPCとなる。",
182
+ ]
183
+ ),
184
+ 'C' => DeathChart.new(
185
+ '環境',
186
+ [
187
+ "何も無し。キミは黒い噂を握りつぶした。",
188
+ "以後、イベント終了時まで、全ての判定の成功率-10%。",
189
+ "ピンチ! 以後、ラウンド終了時まで、キミはカルマを使用できない。",
190
+ "悪い噂が流れる。キミは〈交渉〉判定を行なう。失敗した場合、キミは仲間からの信頼を失って[無縁]され、NPCとなる。",
191
+ "以後、イベント終了時まで、代償にクレジットを消費するパワーを使用できない。",
192
+ "キミの悪評が世間に知れ渡る。協力者からの支援が打ち切られる。以後、シナリオ終了時まで、全ての判定の成功率-20%。",
193
+ "裏切り!! キミは〈経済〉-20%の判定を行なう。失敗した場合、キミは周囲からの信頼を失い、[無縁]され、NPCとなる。",
194
+ "以後、シナリオ終了時まで、【環境】系の技能のレベルがすべて0となる。",
195
+ "捏造報道? 身に覚えのない背信行為がスクープとして報道される。キミは〈心理〉-30%の判定を行なう。失敗した場合、キミは人としての尊厳を失い、[無縁]を受ける。",
196
+ "以後、イベント終了時まで、全ての判定の成功率-30%。",
197
+ "キミの名は史上最悪の汚点として歴史に刻まれる。もはらキミを信じる仲間はなく、キミを助ける社会もない。キミは[無縁]され、以後NPCとなる。",
198
+ ]
199
+ )
200
+ }.freeze
201
+
202
+ TABLES = {
203
+ "CPC" => DiceTable::Table.new(
204
+ "チャレンジ・ペナルティ・チャート",
205
+ "1D10",
206
+ [
207
+ "逝去\n助けるべきNPC(ヒロインなど)が死亡する。",
208
+ "黒星\n敵が目的を成就し、事件はPCの敗北で終了する。そのまま余韻フェイズへ。",
209
+ "活性\n敵のボスのライフを2倍にしたうえで決戦フェイズを開始する。",
210
+ "攻勢\n敵ボスの与ダメージに+2D6の修正を与えたうえで決戦フェイズを開始する。",
211
+ "大挙\n敵の数(ボス以外)を2倍にしたうえで決戦フェイズを開始する。",
212
+ "暗黒\nすべてのエリアを[暗闇]にしたうえで決戦フェイズを開始する。",
213
+ "猛火\n2つの戦場エリアを[ダメージゾーン2]にして、決戦フェイズを開始する。",
214
+ "伏兵\n敵の半分をエリア1とエリア2に移動させた状態で決戦フェイズを開始する。",
215
+ "満腹\nボス以外の敵のライフをすべて2倍にしたうえで決戦フェイズを開始する。",
216
+ "封印\n決戦フェイズの間、PCはカルマを使用できない。決戦フェイズを開始する。"
217
+ ]
218
+ ),
219
+ "STC" => DiceTable::Table.new(
220
+ "サイドトラック・チャート",
221
+ "1D10",
222
+ [
223
+ "邂逅\n偶然、NPCと出会う。どのNPCが現れるかはGMが決定すること。",
224
+ "事故\n交通事故に出くわす。周囲ではパニックが起きているかも知れない。",
225
+ "午睡\n強烈な睡魔に襲われる。まさか、新手のヴィランの能力か?",
226
+ "告白\nNPCのひとりから、今まで秘めていた思いを吐露される。",
227
+ "設定\n新たな設定が明かされる。実はNPCの父だったとか、生来目が見えん、とか。",
228
+ "刺客\n何者かから攻撃を受ける。第3勢力か?",
229
+ "会敵\n偶然、仇敵のひとりと出くわす。追うべきか? 無視すべきか?",
230
+ "不審\n怪しい人物を見かける。追うべきか? 無視すべきか?",
231
+ "遭遇\nシナリオと関係のないヴィラン組織と遭遇する。",
232
+ "平和\n特に何も起きなかった。",
233
+ ]
234
+ ),
235
+ }.freeze
236
+
237
+ register_prefix(
238
+ 'BJ',
239
+ 'DC[LSC]',
240
+ TABLES.keys
241
+ )
242
+ end
243
+ end
244
+ end
@@ -16,7 +16,7 @@ module BCDice
16
16
  HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
17
  ・1D100で判定時に成否、Botchを判定
18
18
   例)1D100<=50
19
-    Chill3 : (1D100<=50) > 55 > Botch
19
+    (1D100<=50) > 55 > Botch
20
20
  INFO_MESSAGE_TEXT
21
21
 
22
22
  def result_1d100(total, dice_total, cmp_op, target)
@@ -30,21 +30,21 @@ module BCDice
30
30
  if tens == ones
31
31
  if (total > target) || (dice_total == 100) # 00は必ず失敗
32
32
  if target > 100 # 目標値が100を超えている場合は、00を振ってもBotchにならない
33
- return Result.failure("失敗")
33
+ return Result.failure("Failure")
34
34
  else
35
35
  return Result.fumble("Botch")
36
36
  end
37
37
  else
38
- return Result.critical("C成功")
38
+ return Result.critical("Colossal Success")
39
39
  end
40
40
  elsif (total <= target) || (dice_total == 1) # 01は必ず成功
41
41
  if total <= (target / 2)
42
- return Result.success("H成功")
42
+ return Result.success("High Success")
43
43
  else
44
- return Result.success("L成功")
44
+ return Result.success("Low Success")
45
45
  end
46
46
  else
47
- return Result.failure("失敗")
47
+ return Result.failure("Failure")
48
48
  end
49
49
  end
50
50
  end
@@ -19,7 +19,7 @@ module BCDice
19
19
 
20
20
  # ダイスボットの使い方
21
21
  HELP_MESSAGE = <<~MESSAGETEXT
22
- xCD@z>=y: x個の10面ダイスで目標値y、クリティカルラインzの判定を行う
22
+ xCD@z>=y: x個の10面ダイスで目標値y(省略時5)、クリティカルラインz(省略時10)の判定を行う。
23
23
  SLT: 技能レベル表を振る
24
24
  DCT: 遅延イベント表を振る
25
25
  MESSAGETEXT
@@ -87,7 +87,7 @@ module BCDice
87
87
  parser = Command::Parser.new('CD', round_type: round_type)
88
88
  .has_prefix_number
89
89
  .enable_critical
90
- .restrict_cmp_op_to(:>=)
90
+ .restrict_cmp_op_to(:>=, nil)
91
91
  cmd = parser.parse(command)
92
92
 
93
93
  unless cmd
@@ -95,8 +95,9 @@ module BCDice
95
95
  end
96
96
 
97
97
  dice_list = @randomizer.roll_barabara(cmd.prefix_number, 10)
98
- critical = cmd.critical&.clamp(cmd.target_number, 10) || 10
99
- succeed_num = dice_list.count { |x| x >= cmd.target_number }
98
+ target_num = cmd.target_number || 5
99
+ critical = cmd.critical&.clamp(target_num, 10) || 10
100
+ succeed_num = dice_list.count { |x| x >= target_num }
100
101
  critical_num = dice_list.count { |x| x >= critical }
101
102
 
102
103
  text = [
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice/game_system/Cthulhu"
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class Cthulhu_English < Cthulhu
8
+ # ゲームシステムの識別子
9
+ ID = 'Cthulhu:English'
10
+
11
+ # ゲームシステム名
12
+ NAME = 'Call of Cthulhu'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = '国際化:English:Call of Cthulhu'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
19
+ c=Critical Rate / f=Fumble Rate / s=Special
20
+
21
+ 1d100<=n c・f・s AllOff(Does Simple Numeric Comparison Only)
22
+
23
+ ・Roll Command that determines cfs
24
+
25
+ CC Does a 1d100 roll c=1、f=100
26
+ CCB Same as above、c=5、f=96
27
+
28
+ Ex:CC<=80 (Rolls using 80 as skill value with 1% cf rule applied)
29
+ Ex:CCB<=55 (Rolls using 55 as skill value with 5% cf rule applied)
30
+
31
+ ・About Roll Combination
32
+
33
+ CBR(x,y) c=1、f=100
34
+ CBRB(x,y) c=5、f=96
35
+
36
+ ・About Opposed Rolls
37
+ RES(x-y) c=1、f=100
38
+ RESB(x-y) c=5、f=96
39
+
40
+ ※Malfunction Number Determination
41
+
42
+ ・CC(x) c=1、f=100
43
+ x=Malfunction Number. Outputs(text "Fumble&Malfunction")together, when roll result is equal or above x, and fumble happens simultaneously.
44
+ If not a fumble, outputs text "Malfunction" regardless of success/failure(Outputs the overwritten result, not outputting success/failure)
45
+
46
+ ・CCB(x) c=5、f=96
47
+ Same as above
48
+ INFO_MESSAGE_TEXT
49
+
50
+ register_prefix_from_super_class()
51
+
52
+ def initialize(command)
53
+ super(command)
54
+
55
+ @locale = :en_us
56
+ end
57
+ end
58
+ end
59
+ end
@@ -44,8 +44,18 @@ module BCDice
44
44
   STOREA :店主またはレジ係
45
45
   STOREB :変わった客その1
46
46
   STOREC :変わった客その2
47
+ ・夜の市
48
+  NMCT :商品の分野
49
+  NMCFO :食品とドラッグ
50
+  NMCME :個人用電子機器
51
+  NMCWE :武器と防具
52
+  NMCCY :サイバーウェア
53
+  NMCFA :衣料品とファッションウェア
54
+  NMCSU :サバイバル用品
47
55
  HELP
48
56
 
57
+ TABLES = translate_tables(@locale)
58
+
49
59
  # 判定の正規表現
50
60
  CP_RE = /^CP(?<ability>\d+)?(?<modifier>[+-]\d+)?(?<target>>=\d+)?/.freeze
51
61
 
@@ -105,21 +115,21 @@ module BCDice
105
115
  result.text += ' > '
106
116
 
107
117
  if result.critical?
108
- result.text += '決定的成功!'
118
+ result.text += "#{translate('CyberpunkRed.critical')}"
109
119
  result.text += "#{dices.last}[#{dices.last}] > "
110
120
  end
111
121
  if result.fumble?
112
- result.text += '決定的失敗!'
122
+ result.text += "#{translate('CyberpunkRed.fumble')}"
113
123
  result.text += "#{dices.last}[#{dices.last}] > "
114
124
  end
115
125
 
116
126
  result.text += total.to_s
117
127
 
118
128
  if result.success?
119
- result.text += '成功'
129
+ result.text += "#{translate('success')}"
120
130
  end
121
131
  if result.failure?
122
- result.text += '失敗'
132
+ result.text += "#{translate('failure')}"
123
133
  end
124
134
 
125
135
  return result
@@ -64,7 +64,7 @@ module BCDice
64
64
  result += " > #{successValue}#{targetText}"
65
65
 
66
66
  if target > 0
67
- if successValue >= target
67
+ if successValue >= target
68
68
  result += " > 【成功】"
69
69
  else
70
70
  result += " > 【失敗】"