bcdice 3.14.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/i18n/Cthulhu/zh_hant.yml +1 -1
  4. data/i18n/CyberpunkRed/ko_kr.yml +389 -0
  5. data/i18n/DoubleCross/ja_jp.yml +53 -0
  6. data/i18n/DoubleCross/ko_kr.yml +52 -0
  7. data/i18n/FutariSousa/ja_jp.yml +138 -138
  8. data/i18n/KillDeathBusiness/ja_jp.yml +198 -0
  9. data/i18n/MagicaLogia/ko_kr.yml +2 -2
  10. data/i18n/MonotoneMuseum/ko_kr.yml +227 -0
  11. data/i18n/SkynautsBouken/ko_kr.yml +114 -0
  12. data/i18n/StratoShout/ko_kr.yml +102 -102
  13. data/i18n/zh_hant.yml +5 -0
  14. data/lib/bcdice/game_system/Aionia.rb +131 -0
  15. data/lib/bcdice/game_system/Arianrhod_Korean.rb +2 -0
  16. data/lib/bcdice/game_system/ArknightsFan.rb +245 -87
  17. data/lib/bcdice/game_system/BlackJacket_Korean.rb +244 -0
  18. data/lib/bcdice/game_system/CharonSanctions.rb +112 -0
  19. data/lib/bcdice/game_system/Cthulhu7th.rb +1 -1
  20. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/full_auto.rb +293 -0
  21. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional/rollable.rb +43 -0
  22. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +470 -306
  23. data/lib/bcdice/game_system/CyberpunkRed.rb +1 -2
  24. data/lib/bcdice/game_system/CyberpunkRed_Korean.rb +66 -0
  25. data/lib/bcdice/game_system/DoubleCross.rb +18 -1
  26. data/lib/bcdice/game_system/DoubleCross_Korean.rb +5 -1
  27. data/lib/bcdice/game_system/FullFace.rb +25 -3
  28. data/lib/bcdice/game_system/FutariSousa.rb +17 -5
  29. data/lib/bcdice/game_system/Garactier.rb +479 -0
  30. data/lib/bcdice/game_system/GardenOrder.rb +390 -9
  31. data/lib/bcdice/game_system/GundogRevised.rb +8 -8
  32. data/lib/bcdice/game_system/KillDeathBusiness.rb +155 -3
  33. data/lib/bcdice/game_system/KimitoYell.rb +568 -0
  34. data/lib/bcdice/game_system/Magius.rb +125 -0
  35. data/lib/bcdice/game_system/Magius_3rdNewTokyoCity.rb +62 -0
  36. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
  37. data/lib/bcdice/game_system/NSSQ.rb +17 -9
  38. data/lib/bcdice/game_system/NervWhitePaper.rb +129 -0
  39. data/lib/bcdice/game_system/RogueLikeHalf.rb +198 -0
  40. data/lib/bcdice/game_system/RuneQuestRoleplayingInGlorantha.rb +16 -13
  41. data/lib/bcdice/game_system/ShinobiGami.rb +73 -43
  42. data/lib/bcdice/game_system/SkynautsBouken.rb +4 -4
  43. data/lib/bcdice/game_system/SkynautsBouken_Korean.rb +57 -0
  44. data/lib/bcdice/game_system/StratoShout_Korean.rb +1 -1
  45. data/lib/bcdice/game_system/SwordWorld.rb +4 -0
  46. data/lib/bcdice/game_system/SwordWorld2_5.rb +3 -2
  47. data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +51 -17
  48. data/lib/bcdice/game_system/TheIndieHack.rb +82 -0
  49. data/lib/bcdice/game_system/TorgEternity.rb +35 -6
  50. data/lib/bcdice/game_system/WoW.rb +161 -0
  51. data/lib/bcdice/game_system/YankeeMustDie.rb +192 -0
  52. data/lib/bcdice/game_system/YearZeroEngine.rb +225 -28
  53. data/lib/bcdice/game_system/YuMyoKishi.rb +141 -0
  54. data/lib/bcdice/game_system/sword_world/rating_lexer.rb +1 -0
  55. data/lib/bcdice/game_system/sword_world/rating_options.rb +4 -1
  56. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +5 -0
  57. data/lib/bcdice/game_system/sword_world/rating_parser.rb +129 -115
  58. data/lib/bcdice/game_system.rb +15 -0
  59. data/lib/bcdice/version.rb +1 -1
  60. metadata +22 -6
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class WoW < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'WoW'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'ワンダーオブワンダラー'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'わんたあおふわんたらあ'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
+ 行為判定 nWW12@s#f<=x
18
+ n: ダイス数
19
+ @s = 大成功値(省略可:デフォルトは1)
20
+ #f = 大失敗値(省略可:デフォルトは12)
21
+ x = 目標値(省略可:デフォルトは6)
22
+ 例)1WW12 5WW12<=6 6WW12@5#3<=7+1
23
+
24
+ ランダムギフトガチャ表 GG
25
+ ランダムギフトガチャ表(アルファベット指定) GGx 例)GGA GGB
26
+
27
+ ファンブル表 FT
28
+ INFO_MESSAGE_TEXT
29
+
30
+ register_prefix('\d*WW12', 'GG', 'GGA', 'GGB', 'GGC', 'GGD', 'GGE', 'GGF', 'GGG', 'GGH', 'FT')
31
+
32
+ TABLES = {
33
+ 'A' => [
34
+ '演者の声', '言いくるめ', '誤魔化し', '代弁者', '腕利き弁護人', '魔性', '魔術', '魔法的物理', '誤り指摘', '専門知識', '理力増幅', '協力的な有識者'
35
+ ],
36
+ 'B' => [
37
+ '百科全書', '地道な下調べ', '思い…出した!', '目星', 'ハッキング', '再考察', '迷探偵', '逆転の発想', '炯眼', '安楽椅子探偵', '密室トリック解明', '丁寧な処置'
38
+ ],
39
+ 'C' => [
40
+ '慈愛', 'クイックヒール', 'エリアヒール', 'クリアランス', '俯瞰視点', 'パターン化', '瞬時看破', '警鐘', '賢者の瞳', '千里眼', '危険感知', 'リバーサル'
41
+ ],
42
+ 'D' => [
43
+ '転禍為福', '受け身', '九死に一生', '軽業', 'バックドア', '着服', '闇に隠れる', '変装', '証拠隠滅', 'サポート', '技師の指', '妨害'
44
+ ],
45
+ 'E' => [
46
+ 'ゴッドハンド', '生存者の切り札', '狙撃', 'プラチナ免許', 'ドライバーズ・ハイ', '相乗り', '愛車/愛馬', 'ビーストフレンズ', 'ドゥ・ライブ', 'カツアゲ', 'マッドドッグ', '目の上の瘤'
47
+ ],
48
+ 'F' => [
49
+ '叱咤激励', 'ふいに見せた優しさ', 'スゴ味', '達人', '必殺技', '二刀流', '急所狙い', 'ジャンプショット', 'パルクール', '疾風怒濤', 'スパート', '走為上'
50
+ ],
51
+ 'G' => [
52
+ 'ヒット&アウェイ', 'ウーバー', '割れもの注意', 'もしもの備え', 'アブダクション', '追加機材', '自在配送', '不屈の精神', '防壁', '心頭滅却', '三時間しか寝てない', 'βエンドルフィン'
53
+ ],
54
+ 'H' => [
55
+ '怒髪天', '頭の体操', '精神統一', 'リトルラック', 'いいね!', '幻視', '慎重性', 'バレットストッパー', '褪せぬ想い', 'アピール上手', '土俵際の魔術師', '真実の愛'
56
+ ],
57
+ 'FT' => [
58
+ '何も起きなかった! ラッキー(?)',
59
+ 'ランダムに武器または防具が外れる。該当箇所に何も装備していなければ1点のダメージ(軽減無効)を受ける。',
60
+ 'GMの指定したLOVEの【深度】が1増加する。誰かに対するLOVEを新規取得させても良い。',
61
+ 'GMの指定したハンドアウト1つの強度が[自身のソウルLV/2]増加する。',
62
+ '1点のダメージ(軽減無効)を受ける。',
63
+ 'プレイス内のPCが所持している消耗品からGMが1つ指定し、破壊する。破壊したくない場合、かわりに自身のHPを最大値の1/3(切り捨て)減らす。',
64
+ '不調強度[自身のソウルLV/2]のランダムな不調を受ける。',
65
+ 'ファンブル表を2回振る。この効果は判定につき1度までで、以降は1点のダメージ(軽減無効)を受ける。',
66
+ 'ランダムなLOVEの【深度】が1減少する。',
67
+ 'ランダムなLOVEの【エモ】が2増加する。',
68
+ 'トラブルが発生する。ランダムトラブル表を使用し、場にトラブルのハンドアウトを追加する。',
69
+ 'ランダムなギフト1つのMPが0になる。'
70
+ ]
71
+ }.freeze
72
+
73
+ def eval_game_system_specific_command(command)
74
+ case command
75
+ when 'GG'
76
+ return roll_gg
77
+ when /^GG([A-H])$/
78
+ return roll_table(::Regexp.last_match(1))
79
+ when 'FT'
80
+ return roll_fumble_table
81
+ else
82
+ return roll_wow(command)
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def roll_gg
89
+ dice_results = @randomizer.roll_barabara(2, 12)
90
+ first_roll = dice_results[0]
91
+ second_roll = dice_results[1]
92
+
93
+ if first_roll >= 9
94
+ return "GG > 自由(アルファベットを決めてGGXを振る)"
95
+ end
96
+
97
+ alphabet = (64 + first_roll).chr
98
+ table = TABLES[alphabet]
99
+ return "ランダムギフトガチャ #{alphabet}-#{second_roll} > #{table[second_roll - 1]}"
100
+ end
101
+
102
+ def roll_table(alphabet)
103
+ table = TABLES[alphabet]
104
+ dice_result = @randomizer.roll_once(12)
105
+ return "ランダムギフトガチャ #{alphabet}-#{dice_result} > #{table[dice_result - 1]}"
106
+ end
107
+
108
+ def roll_fumble_table
109
+ dice_result = @randomizer.roll_once(12)
110
+ table = TABLES['FT']
111
+ return "FT(#{dice_result}) > #{table[dice_result - 1]}"
112
+ end
113
+
114
+ def roll_wow(command)
115
+ # コマンドの解析
116
+ m = /^(\d+)WW12(?:@(\d+))?(?:#(\d+))?(?:<=(\d+))?$/.match(command)
117
+ return nil unless m
118
+
119
+ num_dice = m[1].to_i # 振るダイスの数
120
+ critical_success_value = m[2] ? m[2].to_i : 1 # 大成功の値(デフォルトは1)
121
+ critical_fail_value = m[3] ? m[3].to_i : 12 # 大失敗の値(デフォルトは12)
122
+ success_threshold = m[4] ? m[4].to_i : 6 # 成功の閾値(デフォルトは6)
123
+
124
+ if m[4].nil?
125
+ command_with_defaults = "#{m[1]}WW12<=#{success_threshold}"
126
+ else
127
+ command_with_defaults = command
128
+ end
129
+
130
+ # ダイスを振る
131
+ dice_results = @randomizer.roll_barabara(num_dice, 12)
132
+
133
+ # 出目を分類
134
+ critical_success = dice_results.count { |r| r <= critical_success_value } # 大成功の数
135
+ critical_fail = dice_results.count { |r| r >= critical_fail_value } # 大失敗の数
136
+ normal_success = dice_results.count { |r| (r > critical_success_value) && (r <= success_threshold) && r < critical_fail_value }
137
+
138
+ critical_success_first = critical_success
139
+ critical_fail_first = critical_fail
140
+
141
+ # 大成功と大失敗の相殺
142
+ offset = [critical_success, critical_fail].min
143
+ critical_success -= offset
144
+ critical_fail -= offset
145
+
146
+ # 成功数とファンブルの判定
147
+ successes = normal_success + (critical_success * 2)
148
+ is_fumble = critical_fail > 0
149
+
150
+ # 結果をBCDICE::Resultで構造化
151
+ BCDice::Result.new.tap do |r|
152
+ r.text = "(#{command_with_defaults}) > [#{dice_results.join(',')}] > 成功数#{successes}(大成功#{critical_success_first}個、大失敗#{critical_fail_first}個)#{is_fumble ? ' > ファンブル!' : ''}"
153
+ r.critical = critical_success > 0
154
+ r.fumble = is_fumble
155
+ r.success = successes > 0 && !is_fumble # 成功数が0より大きく、ファンブルがない場合に成功
156
+ r.failure = successes == 0 || is_fumble # 成功数が0、またはファンブルがある場合に失敗
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class YankeeMustDie < Base
6
+ # ゲームシステムの識別子
7
+ ID = "YankeeMustDie"
8
+
9
+ # ゲームシステム名
10
+ NAME = "ヤンキーマストダイ"
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = "やんきいますとたい"
14
+
15
+ HELP_MESSAGE = <<~TEXT
16
+ ■ 判定の方法
17
+ 基本形式:
18
+ (YD+a>=b) または (YD+a>b)
19
+ a:能力値、技能レベル、ドウグ等による修正値(複数指定可)
20
+ b:目標となる成功段階
21
+
22
+ ■ 成功の条件
23
+ >=b:目標となる成功段階b以上の場合に成功となります。この条件では、目標となる成功段階と同じ数値でも成功とみなされます。
24
+ >b:目標となる成功段階bより高い成功段階を出した場合に成功となります。この条件では、目標となる成功段階と同じ数値では失敗となります。
25
+
26
+ ■ 各種表
27
+  関係表 RT
28
+  場面表 ST
29
+  ハプニング表 HT
30
+  闇堕ち表 DT
31
+ TEXT
32
+
33
+ def initialize(command)
34
+ super(command)
35
+ @sort_barabara_dice = true
36
+ @sides_implicit_d = 10
37
+ end
38
+
39
+ def eval_game_system_specific_command(command)
40
+ return check_action(command) || roll_tables(command, TABLES)
41
+ end
42
+
43
+ def check_action(command)
44
+ parser = Command::Parser.new("YD", round_type: @round_type)
45
+ .restrict_cmp_op_to(:>=, :>, nil)
46
+ parsed = parser.parse(command)
47
+ unless parsed
48
+ return nil
49
+ end
50
+
51
+ dice_all = []
52
+ loop do
53
+ dice_list = @randomizer.roll_barabara(3, 10).sort
54
+ dice_all.push(dice_list)
55
+ break unless dice_list.uniq.one?
56
+ end
57
+
58
+ achievement_value = dice_all.flatten.sum(parsed.modify_number)
59
+ if achievement_value <= 9
60
+ success_level = 0
61
+ elsif achievement_value <= 19
62
+ success_level = 1
63
+ elsif achievement_value <= 29
64
+ success_level = 2
65
+ elsif achievement_value <= 39
66
+ success_level = 3
67
+ elsif achievement_value <= 49
68
+ success_level = 4
69
+ elsif achievement_value <= 59
70
+ success_level = 5
71
+ elsif achievement_value <= 69
72
+ success_level = 6
73
+ elsif achievement_value <= 79
74
+ success_level = 7
75
+ elsif achievement_value <= 89
76
+ success_level = 8
77
+ elsif achievement_value <= 99
78
+ success_level = 9
79
+ else
80
+ success_level = 10
81
+ end
82
+
83
+ if parsed.cmp_op == :>
84
+ is_success = success_level > parsed.target_number
85
+ is_failure = !is_success
86
+ success_message = is_success ? '成功' : '失敗'
87
+ elsif parsed.cmp_op == :>=
88
+ is_success = success_level >= parsed.target_number
89
+ is_failure = !is_success
90
+ success_message = is_success ? '成功' : '失敗'
91
+ else
92
+ is_success = false
93
+ is_failure = false
94
+ success_message = nil
95
+ end
96
+
97
+ dice_to_message_arr = []
98
+ dice_all.each do |arr|
99
+ dice_to_message_arr.append("#{arr.sum}[#{arr.join(',')}]")
100
+ end
101
+
102
+ sequence = [
103
+ parsed.to_s,
104
+ format("#{dice_to_message_arr.join(' + ')} %+d", parsed.modify_number),
105
+ achievement_value,
106
+ "成功段階#{success_level}"
107
+ ]
108
+
109
+ if success_message
110
+ sequence.append(success_message)
111
+ end
112
+
113
+ Result.new.tap do |r|
114
+ r.text = sequence.join(" > ")
115
+ r.success = is_success
116
+ r.failure = is_failure
117
+ end
118
+ end
119
+
120
+ TABLES = {
121
+ 'RT' => DiceTable::Table.new(
122
+ '関係表',
123
+ '1D10',
124
+ [
125
+ 'マブダチ:相手とは、マブダチ(親友) だ。いつからマブダチなのかはプレイヤー同士で相談して決めること。',
126
+ '先輩/後輩:相手とは、先輩と後輩の間柄だ。なんの先輩後輩かはプレイヤー同士で相談して決めること。',
127
+ '兄弟:相手とは、血縁であったり契りを交わした兄弟だ。兄弟になった経緯はプレイヤー同士で相談して決めること。',
128
+ 'ライバル:相手とは、良きライバル関係にある。どのようなライバル関係かはプレイヤー同士で相談して決めること。',
129
+ '仲間:相手とは、同じチームなどに所属している仲間だ。どんなチームかはプレイヤー同士で相談して決めること。',
130
+ 'ジモティー:相手とは、同じ地元の仲間、幼馴染だ。いつから幼馴染なのかはプレイヤー同士で相談して決めること。',
131
+ 'おな中:相手とは、出身中学(小学校・高校も可) が同じだ。どんな中学だったのかはプレイヤー同士で決めること。',
132
+ '相棒:相手は、唯一無二の相棒だ。いつから相棒なのかはプレイヤー同士で相談して決めること。',
133
+ 'ゾッコン:相手は、唯一無二の相棒だ。いつから相棒なのかはプレイヤー同士で相談して決めること。',
134
+ '犬猿:相手とは、犬猿の仲である。犬猿の仲であるが、なぜ共に行動するのかはプレイヤー同士で相談して決めること。'
135
+ ]
136
+ ),
137
+ 'ST' => DiceTable::Table.new(
138
+ '場面表',
139
+ '1D10',
140
+ [
141
+ 'サ店(喫茶店)',
142
+ 'クラブ',
143
+ '工業団地',
144
+ '神社/教会',
145
+ '学校',
146
+ '埠頭',
147
+ '繁華街',
148
+ 'ゲーセン',
149
+ '公園',
150
+ '河原'
151
+ # 特殊な場合のみ発生する
152
+ # '病院'
153
+ ]
154
+ ),
155
+ 'HT' => DiceTable::Table.new(
156
+ 'ハプニング表',
157
+ '1D10',
158
+ [
159
+ '単車ドロ:愛車を盗まれる。次の自身の手番を迎えるまで、愛車が1台使用不能になる。所有している愛車が複数ある場合はランダムに1台を選ぶ。',
160
+ '職質:サツにドウグを取り上げられる。次の自身の手番を迎えるまで、素手を除くドウグが1つ使用不能になる。所有しているドウグが複数ある場合はランダムに1つを選ぶ。',
161
+ '不調:どうにも愛車やドウグが体になじまない次の判定の成功段階がー1される。',
162
+ '乱闘:不良との喧嘩に巻き込まれた。PC は1d10 点のダメージを受ける。',
163
+ '大人:悪辣な大人に遭遇して怒りが募る。PC は不良度が1d10 点上昇する',
164
+ '仲違い:つまらないことで喧嘩になって友情に亀裂が入る。場面に登場している【関係】を結んでいるキャラクターの中からランダムに対象を1 人選ぶ。シナリオが終了するまで対象との【関係】が失われる。',
165
+ '悪名:ボスの悪名が広がることによって自然とボスの取り巻きが増える。次の戦闘フェイズにモブが敵として1 人参加する。モブの種類はGM が決定する。',
166
+ '凶暴化:ボスの思考が先鋭化して凶悪になる。シナリオが終了するまでボスが与えるダメージを+2 する。この効果は累積するが、上昇した能力値は戦力には影響しない。',
167
+ '警戒:ボスは自身の周りでうごめく不穏な気配に警戒を強める。ボスの【HP 最大値】と【HP 現在値】を+10 する。この効果は累積する。',
168
+ '不運:ツキがなくなってきた気がする...。ラッキーナンバーの数値が2下がる(最低1)。すでにラッキーナンバーを使用済みであれば効果を受けない。'
169
+ ]
170
+ ),
171
+ 'DT' => DiceTable::Table.new(
172
+ '闇堕ち表',
173
+ '1D10',
174
+ [
175
+ '出奔:すべての人間関係を捨ててどこか遠くへ旅に出る。',
176
+ '半グレ:半グレ集団とつるむようになり、悪事に手を染めるようになる。',
177
+ '指名手配:重大な犯罪を起こして指名手配されて逃亡者となる。',
178
+ '事故:大事故に遭い意識不明の重体となり長期入院する。',
179
+ 'ヤク中:薬物中毒者となり、薬を得るためなら何でもするようになる。',
180
+ '借金:イカれた人間を信奉するようになり多額の借金を背負わされる。',
181
+ '傀儡:悪意を持って人間を利用しようとする勢力に祭り上げられ傀儡と化す。',
182
+ '身代わり:犯罪を犯した人間の身代わりにされて追われる身となる。',
183
+ '逮捕:度を越えた暴力沙汰を度々起こして警察に逮捕される。',
184
+ '失踪:ヤバい事件に首を突っ込んで謎の失踪を遂げる。'
185
+ ]
186
+ )
187
+ }.freeze
188
+
189
+ register_prefix('YD', TABLES.keys)
190
+ end
191
+ end
192
+ end
@@ -14,24 +14,35 @@ module BCDice
14
14
 
15
15
  # ダイスボットの使い方
16
16
  HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
- ・判定コマンド(nYZEx+x+x)
18
- (難易度)YZE(能力ダイス数)+(技能ダイス数)+(アイテムダイス数) # (6のみを数える)
17
+ ・ダイスプール判定コマンド(nYZEx+x+x+m)
18
+ (難易度)YZE(能力ダイス数)+(技能ダイス数)+(アイテムダイス数)+(修正値) # (6のみを数える)
19
+ (難易度)YZE(能力ダイス数)+(技能ダイス数)+(アイテムダイス数)-(修正値) # (6のみを数える)
19
20
 
20
- ・判定コマンド(nMYZx+x+x)
21
+ ・ダイスプール判定コマンド(nMYZx+x+x)
21
22
  (難易度)MYZ(能力ダイス数)+(技能ダイス数)+(アイテムダイス数) # (1と6を数え、プッシュ可能数を表示)
22
23
  (難易度)MYZ(能力ダイス数)-(技能ダイス数)+(アイテムダイス数) # (1と6を数え、プッシュ可能数を表示、技能のマイナス指定)
23
24
 
24
25
  ※ 難易度と技能、アイテムダイス数は省略可能
26
+
27
+ ・ステップダイス判定コマンド(nYZSx+x+m+f)
28
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)+(修正値) # (1,6を数え、プッシュ可能数を表示)
29
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)-(修正値) # (1,6を数え、プッシュ可能数を表示)
30
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)+(修正値)A # (1,6を数え、プッシュ可能数を表示、有利)
31
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)-(修正値)A # (1,6を数え、プッシュ可能数を表示、有利)
32
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)+(修正値)D # (1,6を数え、プッシュ可能数を表示、不利)
33
+ (難易度)YZS(能力ダイス面数)+(技能ダイス面数)-(修正値)D # (1,6を数え、プッシュ可能数を表示、不利)
25
34
  INFO_MESSAGE_TEXT
26
35
 
27
- DIFFICULTY_INDEX = 1 # 難易度のインデックス
28
- COMMAND_TYPE_INDEX = 2 # コマンドタイプのインデックス
29
- ABILITY_INDEX = 3 # 能力値ダイスのインデックス
30
- SKILL_SIGNED_INDEX = 5 # 技能値ダイス符号のインデックス
31
- SKILL_INDEX = 6 # 技能値ダイスのインデックス
32
- GEAR_INDEX = 8 # アイテムダイスのインデックス
36
+ DIFFICULTY_INDEX = 1 # 難易度のインデックス
37
+ COMMAND_TYPE_INDEX = 2 # コマンドタイプのインデックス
38
+ ABILITY_INDEX = 3 # 能力値ダイスのインデックス
39
+ SKILL_SIGNED_INDEX = 5 # 技能値ダイス符号のインデックス
40
+ SKILL_INDEX = 6 # 技能値ダイスのインデックス
41
+ GEAR_INDEX = 8 # アイテムダイスのインデックス
42
+ MODIFIER_SIGNED_INDEX = 10 # 修正値の符号のインデックス
43
+ MODIFIER_INDEX = 11 # 修正値のインデックス
33
44
 
34
- register_prefix('(\d+)?(YZE|MYZ)')
45
+ register_prefix('(\d+)?(YZE|MYZ|YZS)')
35
46
 
36
47
  def dice_info_init()
37
48
  @total_success_dice = 0
@@ -44,16 +55,97 @@ module BCDice
44
55
  end
45
56
 
46
57
  def eval_game_system_specific_command(command)
47
- m = /\A(\d+)?(YZE|MYZ)(\d+)((\+|-)(\d+))?(\+(\d+))?/.match(command)
58
+ resolute_action(command) ||
59
+ resolute_push_action(command) ||
60
+ resolute_step_action(command)
61
+ end
62
+
63
+ def resolute_action(command)
64
+ m = /\A(\d+)?(YZE)(\d+)((\+)(\d+))?(\+(\d+))?((\+|-)(\d+))?/.match(command)
48
65
  unless m
49
- return ''
66
+ return nil
50
67
  end
51
68
 
52
69
  dice_info_init
53
70
 
54
71
  @difficulty = m[DIFFICULTY_INDEX].to_i
72
+ attribute = m[ABILITY_INDEX].to_i
73
+ skill = m[SKILL_INDEX].to_i
74
+ gear = m[GEAR_INDEX].to_i
75
+ modifier = m[MODIFIER_INDEX].to_i
76
+ if m[MODIFIER_SIGNED_INDEX] == '-'
77
+ if skill >= modifier
78
+ skill -= modifier
79
+ else
80
+ modifier -= skill
81
+ skill = 0
82
+ if gear >= modifier
83
+ gear -= modifier
84
+ else
85
+ modifier -= gear
86
+ gear = 0
87
+ if attribute >= modifier
88
+ attribute -= modifier
89
+ else
90
+ attribute = 0
91
+ end
92
+ end
93
+ end
94
+ else
95
+ skill += modifier
96
+ end
97
+
98
+ @total_success_dice = 0
99
+
100
+ dice_pool = attribute
101
+ ability_dice_text, success_dice, botch_dice = make_dice_roll(dice_pool)
102
+
103
+ @total_success_dice += success_dice
104
+ @total_botch_dice += botch_dice
105
+ @base_botch_dice += botch_dice # 能力ダメージ
106
+ @push_dice += (dice_pool - (success_dice + botch_dice))
107
+
108
+ dice_count_text = "(#{dice_pool}D6)"
109
+ dice_text = ability_dice_text
110
+
111
+ if m[SKILL_INDEX]
112
+ dice_pool = skill
113
+ skill_dice_text, success_dice, botch_dice = make_dice_roll(dice_pool)
114
+
115
+ @total_success_dice += success_dice
116
+ @total_botch_dice += botch_dice
117
+ @skill_botch_dice += botch_dice # 技能ダイスの1はpushで振り直し可能(例えマイナス技能でも)
118
+ @push_dice += (dice_pool - success_dice) # 技能ダイスのみ1を含むので、ここでは1を計算に入れない
119
+
120
+ dice_count_text += "+(#{dice_pool}D6)"
121
+ dice_text += "+#{skill_dice_text}"
122
+ end
123
+
124
+ if m[GEAR_INDEX]
125
+ dice_pool = gear
126
+ gear_dice_text, success_dice, botch_dice = make_dice_roll(dice_pool)
127
+
128
+ @total_success_dice += success_dice
129
+ @total_botch_dice += botch_dice
130
+ @gear_botch_dice += botch_dice # ギアダメージ
131
+ @push_dice += (dice_pool - (success_dice + botch_dice))
132
+
133
+ dice_count_text += "+(#{dice_pool}D6)"
134
+ dice_text += "+#{gear_dice_text}"
135
+ end
136
+
137
+ return make_result_with_yze(dice_count_text, dice_text)
138
+ end
139
+
140
+ def resolute_push_action(command)
141
+ m = /\A(\d+)?(MYZ)(\d+)((\+|-)(\d+))?(\+(\d+))?/.match(command)
142
+ unless m
143
+ return nil
144
+ end
55
145
 
56
- command_type = m[COMMAND_TYPE_INDEX]
146
+ dice_info_init
147
+
148
+ @difficulty = m[DIFFICULTY_INDEX].to_i
57
149
 
58
150
  @total_success_dice = 0
59
151
 
@@ -73,10 +165,7 @@ module BCDice
73
165
  skill_dice_text, success_dice, botch_dice = make_dice_roll(dice_pool)
74
166
 
75
167
  skill_unsigned = m[SKILL_SIGNED_INDEX]
76
- if command_type == 'YZE' && skill_unsigned == '-'
77
- # YZEはシンプルに動作するコマンドなのでマイナス技能の処理は対応しない。
78
- return "YZEコマンドでは技能ダイスをマイナス指定できません。"
79
- elsif command_type == 'MYZ' && skill_unsigned == '-'
168
+ if skill_unsigned == '-'
80
169
  @total_success_dice -= success_dice # マイナス技能の成功は通常の成功と相殺される
81
170
  else
82
171
  @total_success_dice += success_dice
@@ -103,17 +192,7 @@ module BCDice
103
192
  dice_text += "+#{gear_dice_text}"
104
193
  end
105
194
 
106
- return make_result_text(command_type, dice_count_text, dice_text)
107
- end
108
-
109
- def make_result_text(command_type, dice_count_text, dice_text)
110
- if command_type == 'YZE'
111
- return make_result_with_yze(dice_count_text, dice_text)
112
- elsif command_type == 'MYZ'
113
- return make_result_with_myz(dice_count_text, dice_text)
114
- end
115
-
116
- return 'Error' # 到達しないはず
195
+ return make_result_with_myz(dice_count_text, dice_text)
117
196
  end
118
197
 
119
198
  def make_result_with_yze(dice_count_text, dice_text)
@@ -150,6 +229,124 @@ module BCDice
150
229
 
151
230
  return "[#{dice_list.join(',')}]", success_dice, botch_dice
152
231
  end
232
+
233
+ def make_dice_a_roll(count, type)
234
+ dice_list = @randomizer.roll_barabara(count, type)
235
+ botch_dice = dice_list.count(1)
236
+ success_dice = dice_list.count { |val| val >= 6 }
237
+ success_level = success_dice + dice_list.count { |val| val >= 10 }
238
+
239
+ @total_success_dice += success_level
240
+ @total_botch_dice += botch_dice
241
+ @push_dice += (count - (success_dice + botch_dice))
242
+
243
+ return "[#{dice_list.join(',')}]", botch_dice
244
+ end
245
+
246
+ def get_rolling_dice(dice_type1, dice_type2, dice_upgrade)
247
+ dice_type1 = 4 if dice_type1 < 4
248
+ dice_type2 = 4 if dice_type2 < 4
249
+
250
+ while dice_upgrade > 0
251
+ if dice_type1 >= dice_type2
252
+ dice_type2 += 2 if dice_type2 < 12
253
+ else
254
+ dice_type1 += 2 if dice_type1 < 12
255
+ end
256
+ dice_upgrade -= 1
257
+ end
258
+
259
+ while dice_upgrade < 0
260
+ if dice_type1 <= dice_type2
261
+ dice_type2 -= 2 if dice_type2 > 4
262
+ else
263
+ dice_type1 -= 2 if dice_type1 > 4
264
+ end
265
+ dice_upgrade += 1
266
+ end
267
+
268
+ if dice_type1 == 4 && dice_type2 == 4
269
+ dice_type1 = 6
270
+ end
271
+
272
+ return dice_type1, dice_type2
273
+ end
274
+
275
+ def resolute_step_action(command)
276
+ m = /\A(\d+)?(YZS)(\d+)((\+)(\d+))?((\+|-)(\d+))?(A|D)?/.match(command)
277
+ unless m
278
+ return nil
279
+ end
280
+
281
+ dice_info_init
282
+
283
+ @difficulty = m[DIFFICULTY_INDEX].to_i
284
+ attribute = m[ABILITY_INDEX].to_i
285
+ skill = m[SKILL_INDEX].to_i
286
+ modifier = m[7].to_i
287
+ advantage = m[10]
288
+
289
+ dice_count_text = ""
290
+ dice_text = ""
291
+
292
+ dice_type1, dice_type2 = get_rolling_dice(attribute, skill, modifier)
293
+
294
+ if dice_type1 <= dice_type2
295
+ if advantage
296
+ if advantage == "A" && (dice_type1 > 4)
297
+ ability_dice_text, botch_dice = make_dice_a_roll(2, dice_type1)
298
+
299
+ @base_botch_dice += botch_dice # 能力ダメージ
300
+ dice_count_text = "(2D#{dice_type1})"
301
+ dice_text = ability_dice_text
302
+ end
303
+ else
304
+ if dice_type1 > 4
305
+ ability_dice_text, botch_dice = make_dice_a_roll(1, dice_type1)
306
+
307
+ @base_botch_dice += botch_dice # 能力ダメージ
308
+ dice_count_text = "(1D#{dice_type1})"
309
+ dice_text = ability_dice_text
310
+ end
311
+ end
312
+ if dice_type2 > 4
313
+ skill_dice_text, botch_dice = make_dice_a_roll(1, dice_type2)
314
+
315
+ @skill_botch_dice += botch_dice
316
+ dice_count_text += "+" unless dice_count_text == ""
317
+ dice_text += "+" unless dice_text == ""
318
+ dice_count_text += "(1D#{dice_type2})"
319
+ dice_text += skill_dice_text
320
+ end
321
+ else
322
+ if dice_type1 > 4
323
+ ability_dice_text, botch_dice = make_dice_a_roll(1, dice_type1)
324
+
325
+ @base_botch_dice += botch_dice # 能力ダメージ
326
+ dice_count_text = "(1D#{dice_type1})"
327
+ dice_text = ability_dice_text
328
+ end
329
+ if advantage
330
+ if advantage == "A" && (dice_type2 > 4)
331
+ skill_dice_text, botch_dice = make_dice_a_roll(2, dice_type2)
332
+
333
+ @skill_botch_dice += botch_dice
334
+ dice_count_text += "+(2D#{dice_type2})"
335
+ dice_text += "+#{skill_dice_text}"
336
+ end
337
+ else
338
+ if dice_type2 > 4
339
+ skill_dice_text, botch_dice = make_dice_a_roll(1, dice_type2)
340
+
341
+ @skill_botch_dice += botch_dice
342
+ dice_count_text += "+(1D#{dice_type2})"
343
+ dice_text += "+#{skill_dice_text}"
344
+ end
345
+ end
346
+ end
347
+
348
+ return make_result_with_myz(dice_count_text, dice_text)
349
+ end
153
350
  end
154
351
  end
155
352
  end