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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/i18n/Arianrhod/ko_kr.yml +3 -0
  4. data/i18n/Cthulhu/en_us.yml +11 -0
  5. data/i18n/Cthulhu/zh_hant.yml +1 -1
  6. data/i18n/CyberpunkRed/ja_jp.yml +389 -0
  7. data/i18n/CyberpunkRed/ko_kr.yml +389 -0
  8. data/i18n/DoubleCross/ja_jp.yml +53 -0
  9. data/i18n/DoubleCross/ko_kr.yml +52 -0
  10. data/i18n/FinalFantasyXIV/en_us.yml +4 -0
  11. data/i18n/FinalFantasyXIV/ja_jp.yml +4 -0
  12. data/i18n/FutariSousa/ja_jp.yml +284 -127
  13. data/i18n/KillDeathBusiness/ja_jp.yml +198 -0
  14. data/i18n/KizunaBullet/ja_jp.yml +653 -0
  15. data/i18n/MagicaLogia/ko_kr.yml +2 -2
  16. data/i18n/MonotoneMuseum/ja_jp.yml +246 -14
  17. data/i18n/MonotoneMuseum/ko_kr.yml +227 -0
  18. data/i18n/SkynautsBouken/ja_jp.yml +114 -0
  19. data/i18n/SkynautsBouken/ko_kr.yml +114 -0
  20. data/i18n/StratoShout/ko_kr.yml +102 -102
  21. data/i18n/TensaiGunshiNiNaro/ja_jp.yml +126 -0
  22. data/i18n/UnsungDuet/ja_jp.yml +62 -0
  23. data/i18n/UnsungDuet/ko_kr.yml +62 -0
  24. data/i18n/en_us.yml +5 -0
  25. data/i18n/zh_hant.yml +5 -0
  26. data/lib/bcdice/dice_table/range_table.rb +24 -0
  27. data/lib/bcdice/game_system/Agnostos.rb +248 -0
  28. data/lib/bcdice/game_system/Aionia.rb +131 -0
  29. data/lib/bcdice/game_system/AniMalus.rb +99 -59
  30. data/lib/bcdice/game_system/Arianrhod_Korean.rb +32 -0
  31. data/lib/bcdice/game_system/ArknightsFan.rb +245 -87
  32. data/lib/bcdice/game_system/BlackJacket.rb +244 -0
  33. data/lib/bcdice/game_system/BlackJacket_Korean.rb +244 -0
  34. data/lib/bcdice/game_system/CharonSanctions.rb +112 -0
  35. data/lib/bcdice/game_system/ConvictorDrive.rb +5 -4
  36. data/lib/bcdice/game_system/Cthulhu7th.rb +1 -1
  37. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/full_auto.rb +293 -0
  38. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/rollable.rb +43 -0
  39. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +470 -306
  40. data/lib/bcdice/game_system/Cthulhu_English.rb +59 -0
  41. data/lib/bcdice/game_system/CyberpunkRed.rb +15 -6
  42. data/lib/bcdice/game_system/CyberpunkRed_Korean.rb +66 -0
  43. data/lib/bcdice/game_system/DivineCharger.rb +841 -0
  44. data/lib/bcdice/game_system/DoubleCross.rb +18 -1
  45. data/lib/bcdice/game_system/DoubleCross_Korean.rb +5 -1
  46. data/lib/bcdice/game_system/FinalFantasyXIV.rb +115 -0
  47. data/lib/bcdice/game_system/FinalFantasyXIV_English.rb +39 -0
  48. data/lib/bcdice/game_system/FullFace.rb +63 -12
  49. data/lib/bcdice/game_system/FutariSousa.rb +105 -13
  50. data/lib/bcdice/game_system/Garactier.rb +479 -0
  51. data/lib/bcdice/game_system/GardenOrder.rb +390 -9
  52. data/lib/bcdice/game_system/GundogRevised.rb +8 -8
  53. data/lib/bcdice/game_system/Insane_Korean.rb +1 -1
  54. data/lib/bcdice/game_system/InvisibleLiar.rb +79 -0
  55. data/lib/bcdice/game_system/KillDeathBusiness.rb +155 -3
  56. data/lib/bcdice/game_system/KimitoYell.rb +568 -0
  57. data/lib/bcdice/game_system/KizunaBullet.rb +240 -0
  58. data/lib/bcdice/game_system/KyokoShinshoku.rb +51 -8
  59. data/lib/bcdice/game_system/Magius.rb +125 -0
  60. data/lib/bcdice/game_system/Magius_3rdNewTokyoCity.rb +62 -0
  61. data/lib/bcdice/game_system/MonotoneMuseum.rb +14 -1
  62. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
  63. data/lib/bcdice/game_system/NRR.rb +2 -2
  64. data/lib/bcdice/game_system/NSSQ.rb +17 -9
  65. data/lib/bcdice/game_system/NervWhitePaper.rb +129 -0
  66. data/lib/bcdice/game_system/RogueLikeHalf.rb +198 -0
  67. data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +16 -13
  68. data/lib/bcdice/game_system/ShinobiGami.rb +73 -43
  69. data/lib/bcdice/game_system/ShuumatsuBargainWars.rb +203 -0
  70. data/lib/bcdice/game_system/SkynautsBouken.rb +49 -134
  71. data/lib/bcdice/game_system/SkynautsBouken_Korean.rb +57 -0
  72. data/lib/bcdice/game_system/StratoShout_Korean.rb +1 -1
  73. data/lib/bcdice/game_system/SwordWorld.rb +5 -1
  74. data/lib/bcdice/game_system/SwordWorld2_5.rb +3 -2
  75. data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +262 -0
  76. data/lib/bcdice/game_system/TheIndieHack.rb +82 -0
  77. data/lib/bcdice/game_system/TheOneRing2nd.rb +406 -0
  78. data/lib/bcdice/game_system/TheUnofficialHollowKnightRPG.rb +185 -0
  79. data/lib/bcdice/game_system/TorgEternity.rb +35 -6
  80. data/lib/bcdice/game_system/TrailOfCthulhu.rb +139 -0
  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/Warhammer4.rb +124 -3
  85. data/lib/bcdice/game_system/WoW.rb +161 -0
  86. data/lib/bcdice/game_system/YankeeMustDie.rb +192 -0
  87. data/lib/bcdice/game_system/YearZeroEngine.rb +225 -28
  88. data/lib/bcdice/game_system/Yotabana.rb +62 -0
  89. data/lib/bcdice/game_system/YuMyoKishi.rb +141 -0
  90. data/lib/bcdice/game_system/cyberpunk_red/tables.rb +111 -473
  91. data/lib/bcdice/game_system/kizuna_bullet/tables.rb +171 -0
  92. data/lib/bcdice/game_system/sword_world/rating_lexer.rb +1 -0
  93. data/lib/bcdice/game_system/sword_world/rating_options.rb +4 -1
  94. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +5 -0
  95. data/lib/bcdice/game_system/sword_world/rating_parser.rb +129 -115
  96. data/lib/bcdice/game_system.rb +31 -0
  97. data/lib/bcdice/version.rb +1 -1
  98. metadata +50 -6
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice/game_system/kizuna_bullet/tables"
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class KizunaBullet < Base
8
+ # ゲームシステムの識別子
9
+ ID = 'KizunaBullet'
10
+
11
+ # ゲームシステム名
12
+ NAME = 'キズナバレット'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = 'きすなはれつと'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~MESSAGETEXT
19
+ ・ダイスロール
20
+ nDM…n個の6面ダイスを転がして、一番高い出目を採用します。
21
+ ・[調査判定]
22
+ nIN…n個の6面ダイスを転がして、一番高い出目が5以上なら成功します。([パートナーのヘルプ]使用可)
23
+ ・[鎮静判定]
24
+ SEn…2個の6面ダイスを転がして、出目の合計値がn([ヒビワレ]状態の[キズナ]の個数)より高いと成功します。([強制鎮静]使用可)
25
+ ・[解決] [アクション]のダメージと[アクシデント]のダメージ軽減
26
+ nSO…2+n個の6面ダイスを転がして、出目をすべて合計します。(nは減らした【励起値】。省略可能)
27
+ ・各種表
28
+ 日常表・場所 OP
29
+ 日常表・内容 OC
30
+ 日常表・場所と内容 OPC
31
+ 日常表(仕事)・場所 OWP
32
+ 日常表(仕事)・内容 OWC
33
+ 日常表(仕事)・場所と内容 OWPC
34
+ 日常表(休暇)・場所 OHP
35
+ 日常表(休暇)・内容 OHC
36
+ 日常表(休暇)・場所と内容 OHPC
37
+ 日常表(出張)・場所 OTP
38
+ 日常表(出張)・内容 OTC
39
+ 日常表(出張)・場所と内容 OTPC
40
+ ターンテーマ表 TT
41
+ ターンテーマ表・親密 TTI
42
+ ターンテーマ表・クール TTC
43
+ ターンテーマ表・主従 TTH
44
+ 遭遇表・場所 EP
45
+ 遭遇表・登場順 EO
46
+ 遭遇表・状況(初対面) EF
47
+ 遭遇表・状況(知り合い) EA
48
+ 遭遇表・決着 EE
49
+ 遭遇表・場所と登場順と状況(初対面)と決着 EFA
50
+ 遭遇表・場所と登場順と状況(知り合い)と決着 EAA
51
+ 交流表・場所 CP
52
+ 交流表・内容 CC
53
+ 交流表・場所と内容 CPC
54
+ 調査表・ベーシック IB
55
+ 調査表・ダイナミック ID
56
+ 調査表・ベーシックとダイナミック IBD
57
+ ハザード表 HA
58
+ 通常ダイジェスト キミたちに新しい命令が下った(調査が依頼された)。
59
+ 1:その事件の内容は…… NI1
60
+ 2:捜査に向かった場所は…… NI2
61
+ 3:犯人のキセキ使いは…… NI3
62
+ 4:起きた出来事は…… NI4
63
+ 5:バレットの間では…… NI5
64
+ 6:戦いの結末は…… NI6
65
+ 通常ダイジェスト キミたちは旅行(出張)である場所を訪れた。
66
+ 1:その場所とは…… NT1
67
+ 2:そこで始まったのは…… NT2
68
+ 3:極限状態のなかで…… NT3
69
+ 4:犯人のキセキ使いは…… NT4
70
+ 5:バレットの間では…… NT5
71
+ 6:戦いの結末は…… NT6
72
+ ホリデーダイジェスト キミたちは休日に出かけることにした。
73
+ 1:その場所とは…… HH1
74
+ 2:待ち合わせをしたら…… HH2
75
+ 3:そしてなんと…… HH3
76
+ 4:ふたりが決めたのは…… HH4
77
+ 5:結果的に…… HH5
78
+ 6:バレットは最後に…… HH6
79
+ ホリデーダイジェスト キミたちは奇妙な事件に出くわした。
80
+ 1:その場所とは…… HC1
81
+ 2:起きた事件は…… HC2
82
+ 3:犯人のキセキ使いは…… HC3
83
+ 4:犯人を追い詰めるべく…… HC4
84
+ 5:戦いの結果は…… HC5
85
+ 6:バレットは最後に…… HC6
86
+ MESSAGETEXT
87
+
88
+ TABLES = translate_tables(@locale)
89
+
90
+ def initialize(command)
91
+ super(command)
92
+
93
+ @sides_implicit_d = 6
94
+ @round_type = RoundType::CEIL
95
+ @d66_sort_type = D66SortType::NO_SORT
96
+ end
97
+
98
+ def eval_game_system_specific_command(command)
99
+ roll_max(command) || roll_investigate(command) || roll_sedative(command) || roll_solve(command) || roll_tables(command, self.class::TABLES)
100
+ end
101
+
102
+ private
103
+
104
+ # 最大値
105
+ def roll_max(command)
106
+ parser = Command::Parser.new("DM", round_type: @round_type)
107
+ .has_prefix_number
108
+ parsed = parser.parse(command)
109
+ unless parsed
110
+ return nil
111
+ end
112
+
113
+ # 最大値計算
114
+ dice_list = @randomizer.roll_barabara(parsed.prefix_number, 6)
115
+ max = dice_list.max
116
+
117
+ return Result.new.tap do |r|
118
+ # テキストを整形
119
+ r.text = "#{command} > [#{dice_list.join(',')}] > #{max}"
120
+ end
121
+ end
122
+
123
+ # 調査判定
124
+ def roll_investigate(command)
125
+ parser = Command::Parser.new("IN", round_type: @round_type)
126
+ .has_prefix_number
127
+ parsed = parser.parse(command)
128
+ unless parsed
129
+ return nil
130
+ end
131
+
132
+ texts = []
133
+ is_success = false
134
+ is_fumble = false
135
+
136
+ # 最大値計算
137
+ dice_list = @randomizer.roll_barabara(parsed.prefix_number, 6)
138
+ max = dice_list.max
139
+
140
+ if max >= 5
141
+ # 5以上の出目があった場合
142
+ # 成功フラグを立てる
143
+ is_success = true
144
+ # 成功メッセージを追加
145
+ texts.push(translate("KizunaBullet.INVESTIGATE.success"))
146
+ elsif max >= 3
147
+ # 3以上の出目があった場合
148
+ # 失敗メッセージを追加
149
+ texts.push(translate("KizunaBullet.INVESTIGATE.failure"))
150
+ # [パートナーのヘルプ]メッセージを追加
151
+ texts.push(translate("KizunaBullet.INVESTIGATE.partnerHelp"))
152
+ else
153
+ # 上記以外
154
+ # ファンブルフラグを立てる
155
+ is_fumble = true
156
+ # 失敗メッセージを追加
157
+ texts.push(translate("KizunaBullet.INVESTIGATE.failure"))
158
+ # ファンブルメッセージを追加
159
+ texts.push(translate("KizunaBullet.INVESTIGATE.fumble"))
160
+ end
161
+
162
+ return Result.new.tap do |r|
163
+ # テキストを整形
164
+ r.text = "#{command} > [#{dice_list.join(',')}] > #{texts.join('')}"
165
+ # 各種成否を格納
166
+ r.condition = is_success
167
+ r.fumble = is_fumble
168
+ end
169
+ end
170
+
171
+ # 鎮静判定
172
+ def roll_sedative(command)
173
+ parser = Command::Parser.new("SE", round_type: @round_type)
174
+ .has_suffix_number
175
+ parsed = parser.parse(command)
176
+ unless parsed
177
+ return nil
178
+ end
179
+
180
+ text = ''
181
+ is_success = false
182
+
183
+ # 合計値計算
184
+ sum = @randomizer.roll_sum(2, 6)
185
+
186
+ if parsed.suffix_number > 12
187
+ # 目標値が12より大きい場合
188
+ # [晶滅]メッセージを追加
189
+ text = translate("KizunaBullet.SEDATIVE.burst")
190
+ elsif parsed.suffix_number < 6
191
+ # 目標値が6より小さい場合
192
+ # [生存]メッセージを追加
193
+ text = translate("KizunaBullet.SEDATIVE.alive")
194
+ elsif sum > parsed.suffix_number
195
+ # 合計値が目標値より大きい場合
196
+ # 成功フラグを立てる
197
+ is_success = true
198
+ # 成功メッセージを追加
199
+ text = translate("KizunaBullet.SEDATIVE.success")
200
+ else
201
+ # 上記以外
202
+ # [強制鎮静]に必要な[キズナ]のチェック数の計算
203
+ # 目標値と出目の差分を計算
204
+ dif = parsed.suffix_number - sum
205
+ # チェック一つごとに結果に+2
206
+ check = (dif / 2) + 1
207
+ # 失敗メッセージを追加
208
+ text = translate("KizunaBullet.SEDATIVE.failure", check: check.to_s)
209
+ end
210
+
211
+ return Result.new.tap do |r|
212
+ # テキストを整形
213
+ r.text = "#{command} > #{sum} > #{text}"
214
+ # 各種成否を格納
215
+ r.condition = is_success
216
+ end
217
+ end
218
+
219
+ # 解決 [アクション]のダメージと[アクシデント]のダメージ軽減
220
+ def roll_solve(command)
221
+ parser = Command::Parser.new("SO", round_type: @round_type)
222
+ .enable_prefix_number
223
+ parsed = parser.parse(command)
224
+ unless parsed
225
+ return nil
226
+ end
227
+
228
+ # 合計値計算
229
+ sum = @randomizer.roll_sum(parsed.prefix_number.to_i + 2, 6)
230
+
231
+ return Result.new.tap do |r|
232
+ # テキストを整形
233
+ r.text = "#{command} > #{sum}"
234
+ end
235
+ end
236
+
237
+ register_prefix('\d+DM', '\d+IN', 'SE\d+', '\d*SO', TABLES.keys)
238
+ end
239
+ end
240
+ end
@@ -15,7 +15,7 @@ module BCDice
15
15
  # ダイスボットの使い方
16
16
  HELP_MESSAGE = <<~MESSAGETEXT
17
17
  ・判定
18
-  ダイスを指定数ダイスロールして、最も高い出目を出力します。難易度を指定すると成否を判定します。
18
+  ダイスを指定数ダイスロールして、最も高い出目を出力します。難易度を指定すると成否を判定します。オプションでA、Dをつけると、[有利][不利]の条件で振れます(A=[有利]、D=[不利])。
19
19
  KS(x,y)
20
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
21
  y:ダイス数(省略:1)
@@ -25,6 +25,16 @@ module BCDice
25
25
  y:ダイス数(省略:1)
26
26
  z:難易度
27
27
 
28
+ KS(x,y)A>=z([有利]:KS(x,y)の判定を2回行い、それぞれの結果のより大きい方が結果となります)
29
+ 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
30
+ y:ダイス数(省略:1)
31
+ z:難易度
32
+
33
+ KS(x,y)D>=z([不利]:KS(x,y)の判定を2回行い、それぞれの結果のより小さい方が結果となります)
34
+ 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
35
+ y:ダイス数(省略:1)
36
+ z:難易度
37
+
28
38
  ・観測ロール
29
39
   [現実乖離]の段階に応じたダイスを指定数ダイスロールして、最も高い出目を出力します。
30
40
  KR(x)
@@ -62,19 +72,30 @@ module BCDice
62
72
  }.freeze
63
73
 
64
74
  def roll_check(command)
65
- m = /^KS(?:\((\d+),([-+\d]+)?\)|(\d+))(?:>=([-+\d]+))?$/.match(command)
75
+ m = /^KS(?:\(([-+\d]+),([-+\d]+)?\)|(\d+))([AD]?)(?:>=([-+\d]+))?$/.match(command)
66
76
  return nil unless m
67
77
 
68
- dice_size = m[1]&.to_i || m[3].to_i
78
+ dice_size = m[1] ? Arithmetic.eval(m[1], @round_type) : Arithmetic.eval(m[3], @round_type).to_i
69
79
  times = m[2] ? Arithmetic.eval(m[2], @round_type) : 1
70
- target = m[4] && Arithmetic.eval(m[4], @round_type)
80
+ target = m[5] && Arithmetic.eval(m[5], @round_type)
81
+
82
+ advantage = m[4]
71
83
 
72
84
  sides = DICE_SIZE_TO_SIDES[dice_size]
73
85
 
74
86
  return nil if sides.nil? || times.nil?
75
87
 
76
- dice_list = @randomizer.roll_barabara(times, sides).sort
77
- value = dice_list.max.clamp(1, dice_size)
88
+ rolls = Array.new(advantage.empty? ? 1 : 2) { roll_check_once(times, dice_size, sides) }
89
+ values = rolls.map { |v| v[:value] }
90
+
91
+ value =
92
+ if advantage == "A"
93
+ values.max
94
+ elsif advantage == "D"
95
+ values.min
96
+ else
97
+ values.first
98
+ end
78
99
 
79
100
  result =
80
101
  if value == 1
@@ -90,8 +111,8 @@ module BCDice
90
111
  end
91
112
 
92
113
  result.text = [
93
- target ? "(KS(#{dice_size},#{times})>=#{target})" : "(KS(#{dice_size},#{times}))",
94
- ("#{value}[#{dice_list.join(',')}]" if times > 1),
114
+ target ? "(KS(#{dice_size},#{times})#{advantage}>=#{target})" : "(KS(#{dice_size},#{times})#{advantage})",
115
+ format_rolls(rolls),
95
116
  value,
96
117
  result.text,
97
118
  ].compact.join(" > ")
@@ -99,6 +120,28 @@ module BCDice
99
120
  return result
100
121
  end
101
122
 
123
+ def roll_check_once(times, dice_size, sides)
124
+ if times < 1
125
+ dice_list = @randomizer.roll_barabara(2, sides).sort
126
+ value = dice_list.min.clamp(1, dice_size)
127
+ else
128
+ dice_list = @randomizer.roll_barabara(times, sides).sort
129
+ value = dice_list.max.clamp(1, dice_size)
130
+ end
131
+
132
+ return {dice_list: dice_list, value: value}
133
+ end
134
+
135
+ def format_rolls(rolls)
136
+ if rolls.length == 1 && rolls.first[:dice_list].length == 1
137
+ return nil
138
+ end
139
+
140
+ rolls.map do |v|
141
+ v[:dice_list].length == 1 ? v[:value].to_s : "#{v[:value]}[#{v[:dice_list].join(',')}]"
142
+ end.join(", ")
143
+ end
144
+
102
145
  GENJITU_KAIRI_TO_SIDES = [4, 6, 8, 10, 12, 20].freeze
103
146
  REALITY_LINE_TO_TIMES = {
104
147
  3 => 1,
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Magius < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'Magius'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'MAGIUS'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'まきうす'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGETEXT
17
+ ■能力値判定 MA+x>=t x:修正値 t:目標値
18
+ 例)MA>=7: ダイスを2個振って、その結果を表示
19
+
20
+ ■技能値判定 MS+x>=t x:修正値 t:目標値
21
+ 例)MS>=7: ダイスを3個振って、そのうち上位2つを採用し、結果を表示
22
+
23
+ INFO_MESSAGETEXT
24
+
25
+ register_prefix('M[AS]')
26
+
27
+ def initialize(command)
28
+ super(command)
29
+
30
+ @sort_barabara_dice = true # バラバラロール(Bコマンド)でソート有
31
+ end
32
+
33
+ def eval_game_system_specific_command(command)
34
+ resolute_ability_action(command) ||
35
+ resolute_skill_action(command)
36
+ end
37
+
38
+ private
39
+
40
+ def with_symbol(number)
41
+ if number == 0
42
+ return ""
43
+ elsif number > 0
44
+ return "+#{number}"
45
+ else
46
+ return number.to_s
47
+ end
48
+ end
49
+
50
+ # 能力値判定
51
+ # @param [String] command
52
+ # @return [Result]
53
+ def get_result_of_ability_action(total, _dice_add, target)
54
+ if total >= target
55
+ return Result.success("成功")
56
+ else
57
+ return Result.failure("失敗")
58
+ end
59
+ end
60
+
61
+ def resolute_ability_action(command)
62
+ m = /MA([+-]\d+)*>=(\d+)/.match(command)
63
+ return nil unless m
64
+
65
+ modify = m[1] ? Arithmetic.eval(m[1], @round_type) : 0
66
+ target = m[2].to_i
67
+
68
+ dices = @randomizer.roll_barabara(2, 6).sort
69
+ dice_text = dices.join(",")
70
+ dice_add = dices.sum
71
+ total = dice_add + modify
72
+
73
+ result = get_result_of_ability_action(total, dice_add, target)
74
+
75
+ sequence = [
76
+ "(#{command})",
77
+ "[#{dice_text}]#{with_symbol(modify)}",
78
+ total,
79
+ result.text,
80
+ ].compact
81
+
82
+ result.text = sequence.join(" > ")
83
+
84
+ return result
85
+ end
86
+
87
+ # 技能値値判定
88
+ # @param [String] command
89
+ # @return [Result]
90
+ def get_result_of_skill_action(total, _dice_add, target)
91
+ if total >= target
92
+ return Result.success("成功")
93
+ else
94
+ return Result.failure("失敗")
95
+ end
96
+ end
97
+
98
+ def resolute_skill_action(command)
99
+ m = /MS([+-]\d+)*>=(\d+)/.match(command)
100
+ return nil unless m
101
+
102
+ modify = m[1] ? Arithmetic.eval(m[1], @round_type) : 0
103
+ target = m[2].to_i
104
+
105
+ dices = @randomizer.roll_barabara(3, 6).sort
106
+ dice_text = dices.join(",")
107
+ dice_add = dices[1].to_i + dices[2].to_i
108
+ total = dice_add + modify
109
+
110
+ result = get_result_of_skill_action(total, dice_add, target)
111
+
112
+ sequence = [
113
+ "(#{command})",
114
+ "[#{dice_text}]#{with_symbol(modify)}",
115
+ total,
116
+ result.text,
117
+ ].compact
118
+
119
+ result.text = sequence.join(" > ")
120
+
121
+ return result
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdice/game_system/Magius'
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class Magius_3rdNewTokyoCity < Magius
8
+ # ゲームシステムの識別子
9
+ ID = 'Magius_3rdNewTokyoCity'
10
+
11
+ # ゲームシステム名
12
+ NAME = 'MAGIUS:新世紀エヴァンゲリオンRPG 決戦!第3新東京市'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = 'まきうすしんせいきえうあんけりおんRPGけつせんたい3しんとうきようし'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~INFO_MESSAGETEXT
19
+ ■能力値判定 MA+x>=t x:修正値 t:目標値
20
+ 例)MA>=7: ダイスを2個振って、その結果(成功,失敗,絶対成功,絶対失敗)を表示
21
+
22
+ ■技能値判定 MS+x>=t x:修正値 t:目標値
23
+ 例)MS>=7: ダイスを3個振って、そのうち上位2つを採用し、結果(成功,失敗,絶対成功,絶対失敗)を表示
24
+
25
+ INFO_MESSAGETEXT
26
+
27
+ register_prefix('M[AS]')
28
+
29
+ private
30
+
31
+ # 能力値判定の結果取得
32
+ # @param [Integer] total, dice_add, target
33
+ # @return [Result]
34
+ def get_result_of_ability_action(total, dice_add, target)
35
+ if dice_add == 12
36
+ return Result.critical("絶対成功")
37
+ elsif dice_add == 2
38
+ return Result.fumble("絶対失敗")
39
+ elsif total >= target
40
+ return Result.success("成功")
41
+ else
42
+ return Result.failure("失敗")
43
+ end
44
+ end
45
+
46
+ # 技能値判定の結果取得
47
+ # @param [Integer] total, dice_add, target
48
+ # @return [Result]
49
+ def get_result_of_skill_action(total, dice_add, target)
50
+ if dice_add == 12
51
+ return Result.critical("絶対成功")
52
+ elsif dice_add == 2
53
+ return Result.fumble("絶対失敗")
54
+ elsif total >= target
55
+ return Result.success("成功")
56
+ else
57
+ return Result.failure("失敗")
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -25,9 +25,16 @@ module BCDice
25
25
    クリティカル値、ファンブル値は省略可能です。([]ごと省略できます)
26
26
    自動成功、自動失敗、成功、失敗を自動表示します。
27
27
  ・各種表
28
+ 【改訂版環境】
29
+  ・感情表 MET
30
+  ・兆候表(戦闘時) MBOT/兆候表(非戦闘時) MNOT
31
+  ・歪み表 MDT
32
+  ・世界歪曲表 MWDT
33
+  ・永劫消失表 MEDT
34
+ 【旧版環境】
28
35
   ・感情表 ET/感情表 2.0 ET2
29
36
   ・兆候表 OT/兆候表ver2.0 OT2/兆候表ver3.0 OT3
30
-  ・歪み表 DT/歪み表ver2.0 DT2/歪み表(野外) DTO/歪み表(海) DTS/歪み表(館・城) DTM
37
+  ・歪み表 DT/歪み表ver2.0 DT2/歪み表(野外) DTO/歪み表(海) DTS/歪み表(館・城) DTM
31
38
   ・世界歪曲表 WDT/世界歪曲表2.0 WDT2
32
39
   ・永劫消失表 EDT
33
40
  ・D66ダイスあり
@@ -146,6 +153,12 @@ module BCDice
146
153
  "EDT" => DiceTable::Table.from_i18n("MonotoneMuseum.table.EDT", locale),
147
154
  "DTM" => MMTable.from_i18n("MonotoneMuseum.table.DTM", locale),
148
155
  "OT3" => DiceTable::Table.from_i18n("MonotoneMuseum.table.OT3", locale),
156
+ "MET" => DiceTable::D66GridTable.from_i18n("MonotoneMuseum.table.MET", locale),
157
+ "MBOT" => DiceTable::Table.from_i18n("MonotoneMuseum.table.MBOT", locale),
158
+ "MNOT" => DiceTable::Table.from_i18n("MonotoneMuseum.table.MNOT", locale),
159
+ "MDT" => MMTable.from_i18n("MonotoneMuseum.table.MDT", locale),
160
+ "MWDT" => DiceTable::Table.from_i18n("MonotoneMuseum.table.MWDT", locale),
161
+ "MEDT" => DiceTable::Table.from_i18n("MonotoneMuseum.table.MEDT", locale),
149
162
  }
150
163
  end
151
164
  end
@@ -22,11 +22,11 @@ module BCDice
22
22
    크리티컬, 펌블치는 생략가능합니다. ([]자체를 생략가능)
23
23
    자동성공, 자동실패, 성공, 실패를 자동표기합니다.
24
24
  ・각종표
25
-  ・감정표 ET/감정표 2.0 ET2
26
-  ・징조표 OT/징조표ver2.0 OT2/징조표ver3.0 OT3
25
+  ・감정표 ET/감정표 2.0 ET2/개정판 감정표 MET
26
+  ・징조표 OT/징조표ver2.0 OT2/징조표ver3.0 OT3 / 개정판 전투 징조표 MBOT / 개정판 비전투 징조표 MNOT
27
27
   ・일그러짐표 DT/일그러짐표ver2.0 DT2/일그러짐표(야외) DTO/일그러짐표(바다) DTS/일그러짐표(저택・성) DTM
28
-  ・세계왜곡표  WDT/세계왜곡표2.0 WDT2
29
-  ・영구소실표 EDT
28
+  ・세계왜곡표  WDT/세계왜곡표2.0 WDT2/개정판 왜곡표 MDT/개정판 세계왜곡표 MWDT
29
+  ・영구소실표 EDT/개정판 영구소실표 MEDT
30
30
  ・D66다이스 있음
31
31
  INFO_MESSAGE_TEXT
32
32
 
@@ -97,10 +97,10 @@ module BCDice
97
97
  SUCCESSES = [:success, :critical, :miracle].freeze
98
98
  CRITICALS = [:critical, :miracle].freeze
99
99
 
100
- DISADVANTAGE = [:fumble, :fumble, :failure, :failure, :success, :success].freeze
100
+ DISADVANTAGE = [:fumble, :failure, :failure, :failure, :success, :success].freeze
101
101
  NORMAL = [:fumble, :failure, :failure, :failure, :success, :success, :success, :critical].freeze
102
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
103
+ EXTRA = [:fumble, :fumble, :failure, :failure, :success, :success, :critical, :critical, :critical, :critical, :miracle, :miracle].freeze
104
104
 
105
105
  ICON = {
106
106
  fumble: "💀",
@@ -54,7 +54,7 @@ module BCDice
54
54
  total = largest_two.sum + modifier
55
55
  num_1 = dice_list.count(1)
56
56
 
57
- additional_result =
57
+ result =
58
58
  if largest_two == [6, 6]
59
59
  Result.critical(" > 絶対成功!")
60
60
  elsif largest_two == [1, 1]
@@ -73,10 +73,11 @@ module BCDice
73
73
  sequence = [
74
74
  "(#{command})",
75
75
  "[#{dice_list.join(',')}]#{Format.modifier(modifier)}",
76
- "#{total}[#{largest_two.join(',')}]#{additional_result.text}#{fp_result}",
76
+ "#{total}[#{largest_two.join(',')}]#{result.text}#{fp_result}",
77
77
  ]
78
78
 
79
- return sequence.join(" > ")
79
+ result.text = sequence.join(" > ")
80
+ return result
80
81
  end
81
82
 
82
83
  # ダメージロール
@@ -90,24 +91,29 @@ module BCDice
90
91
  resist = m[4].to_i
91
92
 
92
93
  dice_list = @randomizer.roll_barabara(dice_count, 6)
94
+ normal_damage = damage(dice_list, resist)
93
95
 
94
- result = "(#{command}) > [#{dice_list.join(',')}]#{resist} > #{damage(dice_list, resist)}ダメージ"
96
+ result = "(#{command}) > [#{dice_list.join(',')}]#{resist}"
95
97
 
96
98
  critical_target = critical_up ? 1 : 2
97
99
 
98
100
  if dice_list.count(6) - dice_list.count(1) >= critical_target
99
- result += " クリティカルヒット!\n"
100
- result += additional_damage_roll(increase_critical_dice, resist)
101
+ result += critical_damage_roll(increase_critical_dice, resist, normal_damage)
102
+ result = Result.critical(result)
103
+ else
104
+ result += " > #{normal_damage}ダメージ"
105
+ result = normal_damage > 0 ? Result.success(result) : Result.failure(result)
101
106
  end
102
107
 
103
108
  return result
104
109
  end
105
110
 
106
- def additional_damage_roll(increase_critical_dice, resist)
111
+ def critical_damage_roll(increase_critical_dice, resist, normal_damage)
107
112
  dice_count = increase_critical_dice ? 8 : 4
108
113
 
109
114
  dice_list = @randomizer.roll_barabara(dice_count, 6)
110
- "(#{dice_count}DR#{resist}) [#{dice_list.join(',')}]#{resist} > #{damage(dice_list, resist)}ダメージ"
115
+ critical_damage = damage(dice_list, resist)
116
+ return " > クリティカルヒット! > (#{dice_count}DR#{resist}) > [#{dice_list.join(',')}]#{resist} > #{normal_damage + critical_damage}ダメージ"
111
117
  end
112
118
 
113
119
  # 回復ロール
@@ -119,8 +125,10 @@ module BCDice
119
125
  resist = m[2]&.to_i || 3
120
126
 
121
127
  dice_list = @randomizer.roll_barabara(dice_count, 6)
128
+ heal_amount = damage(dice_list, resist)
129
+ result_text = "(#{command}) > [#{dice_list.join(',')}]#{resist} > #{heal_amount}回復"
122
130
 
123
- return "(#{command}) [#{dice_list.join(',')}]#{resist} #{damage(dice_list, resist)}回復"
131
+ return heal_amount > 0 ? Result.success(result_text) : Result.failure(result_text)
124
132
  end
125
133
 
126
134
  def damage(dice_list, resist)