bcdice 3.0.0 → 3.1.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 +25 -1
- data/README.md +32 -0
- data/i18n/MonotoneMuseum/ja_jp.yml +3 -3
- data/lib/bcdice/game_system.rb +1 -0
- data/lib/bcdice/game_system/AlchemiaStruggle.rb +1 -1
- data/lib/bcdice/game_system/Alshard.rb +1 -1
- data/lib/bcdice/game_system/AngelGear.rb +123 -0
- data/lib/bcdice/game_system/ArsMagica.rb +1 -1
- data/lib/bcdice/game_system/BBN.rb +1 -1
- data/lib/bcdice/game_system/BadLife.rb +1 -1
- data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
- data/lib/bcdice/game_system/BeastBindTrinity.rb +2 -2
- data/lib/bcdice/game_system/BlindMythos.rb +1 -1
- data/lib/bcdice/game_system/BloodCrusade.rb +42 -42
- data/lib/bcdice/game_system/BloodMoon.rb +41 -0
- data/lib/bcdice/game_system/CardRanker.rb +2 -2
- data/lib/bcdice/game_system/ChaosFlare.rb +1 -1
- data/lib/bcdice/game_system/Chill.rb +1 -1
- data/lib/bcdice/game_system/CodeLayerd.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu.rb +8 -4
- data/lib/bcdice/game_system/Cthulhu7th.rb +40 -334
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
- data/lib/bcdice/game_system/CthulhuTech.rb +1 -1
- data/lib/bcdice/game_system/DarkBlaze.rb +1 -1
- data/lib/bcdice/game_system/DiceOfTheDead.rb +1 -1
- data/lib/bcdice/game_system/DoubleCross.rb +1 -1
- data/lib/bcdice/game_system/EarthDawn.rb +1 -1
- data/lib/bcdice/game_system/EarthDawn3.rb +1 -1
- data/lib/bcdice/game_system/EarthDawn4.rb +1 -1
- data/lib/bcdice/game_system/Elysion.rb +2 -2
- data/lib/bcdice/game_system/EmbryoMachine.rb +1 -1
- data/lib/bcdice/game_system/EtrianOdysseySRS.rb +1 -1
- data/lib/bcdice/game_system/FullMetalPanic.rb +1 -1
- data/lib/bcdice/game_system/Garako.rb +12 -4
- data/lib/bcdice/game_system/GehennaAn.rb +1 -1
- data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
- data/lib/bcdice/game_system/Gorilla.rb +1 -1
- data/lib/bcdice/game_system/HarnMaster.rb +1 -1
- data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
- data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
- data/lib/bcdice/game_system/Illusio.rb +25 -34
- data/lib/bcdice/game_system/LostRoyal.rb +1 -1
- data/lib/bcdice/game_system/MeikyuDays.rb +1 -1
- data/lib/bcdice/game_system/MeikyuKingdom.rb +2 -2
- data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +2 -2
- data/lib/bcdice/game_system/MetalHeadExtream.rb +1 -1
- data/lib/bcdice/game_system/MetallicGuardian.rb +1 -1
- data/lib/bcdice/game_system/MonotoneMuseum.rb +1 -1
- data/lib/bcdice/game_system/NeverCloud.rb +540 -5
- data/lib/bcdice/game_system/NightWizard.rb +1 -1
- data/lib/bcdice/game_system/NightWizard3rd.rb +1 -1
- data/lib/bcdice/game_system/NinjaSlayer.rb +4 -13
- data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
- data/lib/bcdice/game_system/OracleEngine.rb +1 -1
- data/lib/bcdice/game_system/OrgaRain.rb +17 -25
- data/lib/bcdice/game_system/Paradiso.rb +1 -1
- data/lib/bcdice/game_system/ParanoiaRebooted.rb +1 -1
- data/lib/bcdice/game_system/Postman.rb +1 -1
- data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
- data/lib/bcdice/game_system/RecordOfLodossWar.rb +1 -1
- data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
- data/lib/bcdice/game_system/RokumonSekai2.rb +1 -1
- data/lib/bcdice/game_system/Ryutama.rb +1 -1
- data/lib/bcdice/game_system/SRS.rb +1 -1
- data/lib/bcdice/game_system/SamsaraBallad.rb +1 -1
- data/lib/bcdice/game_system/Satasupe.rb +79 -860
- data/lib/bcdice/game_system/SevenFortressMobius.rb +1 -1
- data/lib/bcdice/game_system/SharedFantasia.rb +1 -1
- data/lib/bcdice/game_system/ShinkuuGakuen.rb +2 -2
- data/lib/bcdice/game_system/ShinobiGami.rb +3 -3
- data/lib/bcdice/game_system/Skynauts.rb +2 -2
- data/lib/bcdice/game_system/SteamPunkers.rb +1 -1
- data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +46 -182
- data/lib/bcdice/game_system/SwordWorld2_0.rb +21 -149
- data/lib/bcdice/game_system/SwordWorld2_5.rb +126 -40
- data/lib/bcdice/game_system/Torg.rb +1 -1
- data/lib/bcdice/game_system/TorgEternity.rb +2 -2
- data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
- data/lib/bcdice/game_system/TwilightGunsmoke.rb +1 -1
- data/lib/bcdice/game_system/UnsungDuet.rb +1 -1
- data/lib/bcdice/game_system/Utakaze.rb +1 -1
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +1 -1
- data/lib/bcdice/game_system/Warhammer.rb +1 -1
- data/lib/bcdice/game_system/Warhammer4.rb +1 -1
- data/lib/bcdice/game_system/WorldOfDarkness.rb +1 -1
- data/lib/bcdice/game_system/YearZeroEngine.rb +1 -1
- data/lib/bcdice/game_system/ZettaiReido.rb +1 -1
- data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +294 -0
- data/lib/bcdice/game_system/cthulhu7th/rollable.rb +41 -0
- data/lib/bcdice/game_system/satasupe/tables.rb +723 -0
- data/lib/bcdice/game_system/sword_world/rating_lexer.rb +47 -0
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +99 -0
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +457 -0
- data/lib/bcdice/game_system/sword_world/transcendent_test.rb +104 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +10 -2
|
@@ -32,10 +32,12 @@ module BCDice
|
|
|
32
32
|
またタイプの軽減化のために末尾に「@クリティカル値」でも処理するようにしました。
|
|
33
33
|
例)K20[10] K10+5[9] k30[10] k10[9]+10 k10-5@9
|
|
34
34
|
|
|
35
|
-
・レーティング表の半減 (HKx)
|
|
35
|
+
・レーティング表の半減 (HKx, KxH+N)
|
|
36
36
|
レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。
|
|
37
|
+
末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。
|
|
38
|
+
この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)
|
|
37
39
|
クリティカル値を指定しない場合、クリティカルなしと扱われます。
|
|
38
|
-
例)HK20 K20h HK10-5@9 K10-5@9H K20gfH
|
|
40
|
+
例)HK20 K20h HK10-5@9 K10-5@9H K20gfH K20+8H+2 K20+8H+(1+1)
|
|
39
41
|
|
|
40
42
|
・ダイス目の修正(運命変転やクリティカルレイ用)
|
|
41
43
|
末尾に「$修正値」でダイス目に修正がかかります。
|
|
@@ -66,54 +68,138 @@ module BCDice
|
|
|
66
68
|
|
|
67
69
|
・絡み効果表 (TT)
|
|
68
70
|
絡み効果表を出すことができます。
|
|
69
|
-
INFO_MESSAGE_TEXT
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
・ドルイドの物理魔法用表 (Dru[2-6の値,7-9の値,10-12の値])
|
|
73
|
+
例)Dru[0,3,6]+10-3
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def replace_text(string)
|
|
77
|
-
return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string)
|
|
75
|
+
・アビスカース表 (ABT)
|
|
76
|
+
アビスカース表を出すことができます。
|
|
77
|
+
INFO_MESSAGE_TEXT
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
register_prefix('H?K\d+', 'Gr(\d+)?', '2D6?@\d+', 'FT', 'TT', 'Dru\[\d+,\d+,\d+\]', 'ABT')
|
|
80
|
+
|
|
81
|
+
ABYSS_CURSE_TABLE = DiceTable::D66GridTable.new(
|
|
82
|
+
'アビスカース表', [
|
|
83
|
+
[
|
|
84
|
+
"「自傷の」 装備時 この武具を装備中に装備者がクリティカルを発生させた時、装備者のHPが5点減少する。",
|
|
85
|
+
"「嘆きの」 装備時 近くに敵がいたり、長い緊張状態が続くと涙が止まらなくなる。戦闘中なら「射程:術者(自身)」「射程:接触」以外の効果で対象を選べなくなる。",
|
|
86
|
+
"「優しき」 装備時 敵に同情してしまう。敵対するキャラクターを対象にする場合、対象のHPが1点以上減少しているなら命中力判定、魔法行使判定に-2のペナルティ修正を受ける。",
|
|
87
|
+
"「差別の」 装備時 特定の分類に対して与える物理ダメージ・魔法ダメージが2点減少する。分類は「分類決定表」で無作為に決定する。",
|
|
88
|
+
"「脆弱な」 装備時 魔法ダメージを受けるたび、そのダメージが+1点される。",
|
|
89
|
+
"「無謀な」 装備時 防護点が2点減少する(最低0)。",
|
|
90
|
+
], [
|
|
91
|
+
"「重い」 装備時 強化した武具の必要筋力が+2される。威力、防護点などは変化なし。",
|
|
92
|
+
"「難しい」 装備時 いかなる威力表使用時でも、③④欄の数値が威力に関係なく「0」になる(自動失敗ではない)。",
|
|
93
|
+
"「軟弱な」 装備時 精神抵抗力判定に-1のペナルティ修正を受ける。",
|
|
94
|
+
"「病弱な」 装備時 生命抵抗力判定に-1のペナルティ修正を受ける。",
|
|
95
|
+
"「過敏な」 装備時 特定の属性から受ける物理ダメージ、魔法ダメージが2点上昇する。属性は「属性決定表」で無作為に決定する。",
|
|
96
|
+
"「陽気な」 装備時 精神抵抗判定に失敗するたび、笑いが止まらなくなる。次の手番終了時まで行動判定(『Ⅰ』123頁)に-1のペナルティ修正を受ける。この効果は累積する。",
|
|
97
|
+
], [
|
|
98
|
+
"「たどたどしい」 装備時 話をする時に言葉に詰まったり、言い間違えたりしやすくなる。魔法行使判定に-1のペナルティ修正を受ける。",
|
|
99
|
+
"「代弁する」 装備時 自身の会話は、そのまま武具が魔法文明語の聞き取りづらい声で話す。装備中は魔法文明語以外の言語で会話は行えず、妖精魔法、魔動機術を行使できなくなる。",
|
|
100
|
+
"「施しは受けない」 装備時 戦闘中、「抵抗:任意」の効果を受け入れた場合、次の手番終了時まで生命抵抗力、精神抵抗力に-2のペナルティ修正を受ける。",
|
|
101
|
+
"「死に近い」 携行時 常に生死判定に「冒険者レベル」と同じ値のペナルティ修正を受ける。",
|
|
102
|
+
"「おしゃれな」 携行時 その武具を常に華美に飾りたくなる。収入を得るたび、その1割以上をこの武具の装飾に費やさなければならない(効果などに変化はない)。",
|
|
103
|
+
"「マナを吸う」 携行時 魔法や練技など、自身の意思でMPを消費する効果を使用する場合、すべてのMP消費が1点上昇する。",
|
|
104
|
+
], [
|
|
105
|
+
"「鈍重な」 携行時 移動力が半分(端数切り上げ)になる。",
|
|
106
|
+
"「定まらない」 携行時 戦闘中の手番開始時に1dし、出目が「1」なら《ターゲッティング》とそれを前提とした戦闘特技を習得していないものとして扱う。",
|
|
107
|
+
"「錯乱の」 携行時 戦闘中の手番開始時に1dし、出目が「1」なら近接攻撃を含む「射程:接触」の対象に効果を使用する際、対象は同じ位置(エリア、座標)の全てのキャラクター(敵味方含む)から無作為に選ばれる。",
|
|
108
|
+
"「足絡みの」 携行時 戦闘中の手番開始時に1dし、出目が「1」ならその場で即座に転倒する。手番中には起き上がれない。",
|
|
109
|
+
"「滑り落ちる」 携行時 戦闘中の手番開始時に1dし、出目が「1」なら手に装備または保持しているものをすべてその場に落とす(その手番の主動作で拾う事は可能)。",
|
|
110
|
+
"「悪臭放つ」 携行時 強い悪臭を放つ。所持しているだけで他のキャラクターに不快感を与え、隠密判定に-2のペナルティ修正を受ける。さらに冒険者ランク(『Ⅱ』137頁)が1段階低いものとして扱われる。",
|
|
111
|
+
], [
|
|
112
|
+
"「醜悪な」 携行時 武具の見た目が悪く、魅力がない。売却する際、基本取引価格の4分の1の価格で売却する。さらに冒険者ランク(『Ⅱ』137頁)が1段階低いものとして扱われる。",
|
|
113
|
+
"「唸る」 携行時 その武具から常に羽虫が飛び交うような音が響く。隠密判定、危険感知判定に-4のペナルティ修正を受ける。",
|
|
114
|
+
"「ふやけた」 携行時 水を吸ったようにふやけた質感をしている。追加ダメージ-1(武器)、防護点-1(鎧、盾)。病気属性の効果に対する生命抵抗力、精神抵抗力判定に-4のペナルティ修正を受ける。",
|
|
115
|
+
"「古傷の」 携行時 HPを回復する効果(休息による回復を含む)を受けた場合、その回復量が1点減少する。",
|
|
116
|
+
"「まばゆい」 携行時 光などを弾いて強く輝く。自身は常に視界が悪い事による-1のペナルティ修正を受ける。",
|
|
117
|
+
"「栄光なき」 携行時 行為判定で自動成功した際、自動成功とは扱わず、2dを振り直し、その後の出目に従う。この効果は1日に1回のみ発揮される。",
|
|
118
|
+
], [
|
|
119
|
+
"「正直者の」 携行時 嘘、方便がすぐばれるようになる。真偽判定の対象となる場合、-4のペナルティ修正を受ける。",
|
|
120
|
+
"「乗り物酔いの」 携行時 揺れに弱くなる。自身の足以外の手段で10分以上移動した後、1時間、行動判定に-1のペナルティ修正を受ける。",
|
|
121
|
+
"「碧を厭う」 携行時 自然の中では落ち着かなくなる。自然環境(『Ⅰ』108頁)では行動判定に-1のペナルティ修正を受ける。",
|
|
122
|
+
"「我慢できない」 携行時 セッション中に1日の始まりを迎えるたび、趣味や嗜好品などに「冒険者レベル×10」ガメルを出費しなければならない。趣味や嗜好品が消費できない環境であれば、翌日の朝まで最大HP、最大MPが「冒険者レベル」点減少する。",
|
|
123
|
+
"「つきまとう」 携行時 この武具が気がつけば身の回りにある。この武具以外での命中力判定、魔法行使判定(武器)、回避力判定(鎧、盾)に-4のペナルティ修正を受ける。",
|
|
124
|
+
"「のろまな」 携行時 戦闘開始処理の「戦闘準備」をいっさい行えなくなる。",
|
|
125
|
+
],
|
|
126
|
+
]
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
ABYSS_CURSE_CATEGORY_TABLE = DiceTable::D66ParityTable.new(
|
|
130
|
+
"アビスカース分類決定表",
|
|
131
|
+
["蛮族", "動物", "植物", "アンデッド", "魔法生物", "「蛮族」「動物」「植物」「アンデッド」「魔法生物」から任意"],
|
|
132
|
+
["魔動機", "幻獣", "妖精", "魔神", "人族", "「魔動機」「幻獣」「妖精」「魔神」「人族」から任意"]
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
ABYSS_CURSE_ATTR_TABLE = DiceTable::D66ParityTable.new(
|
|
136
|
+
"アビスカース属性決定表",
|
|
137
|
+
["土", "水・氷", "炎", "風", "雷", "純粋エネルギー"],
|
|
138
|
+
["断空", "衝撃", "毒", "病気", "呪い", "精神効果"]
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def eval_game_system_specific_command(command)
|
|
142
|
+
case command
|
|
143
|
+
when /^dru\[(\d+),(\d+),(\d+)\]/i
|
|
144
|
+
power_list = Regexp.last_match.captures.map(&:to_i)
|
|
145
|
+
druid_parser = Command::Parser.new(/dru\[\d+,\d+,\d+\]/i, round_type: BCDice::RoundType::CEIL)
|
|
146
|
+
|
|
147
|
+
cmd = druid_parser.parse(command)
|
|
148
|
+
unless cmd
|
|
149
|
+
return nil
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
druid_dice(cmd, power_list)
|
|
153
|
+
when 'ABT'
|
|
154
|
+
get_abyss_curse_table
|
|
155
|
+
else
|
|
156
|
+
super(command)
|
|
82
157
|
end
|
|
83
158
|
end
|
|
84
159
|
|
|
85
|
-
def
|
|
86
|
-
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def getAdditionalString(string, output)
|
|
90
|
-
output, values = super(string, output)
|
|
91
|
-
|
|
92
|
-
keptDiceChangeModify, = getKeptDiceChangesFromString(string)
|
|
93
|
-
|
|
94
|
-
values['keptDiceChangeModify'] = keptDiceChangeModify
|
|
95
|
-
output += "a[#{keptDiceChangeModify}]" if keptDiceChangeModify != 0
|
|
96
|
-
|
|
97
|
-
return output, values
|
|
160
|
+
def rating_parser
|
|
161
|
+
return RatingParser.new(version: :v2_5)
|
|
98
162
|
end
|
|
99
163
|
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
164
|
+
def druid_dice(command, power_list)
|
|
165
|
+
dice_list = @randomizer.roll_barabara(2, 6)
|
|
166
|
+
dice_total = dice_list.sum()
|
|
167
|
+
offset =
|
|
168
|
+
case dice_total
|
|
169
|
+
when 2..6
|
|
170
|
+
0
|
|
171
|
+
when 7..9
|
|
172
|
+
1
|
|
173
|
+
when 10..12
|
|
174
|
+
2
|
|
175
|
+
end
|
|
176
|
+
power = power_list[offset]
|
|
177
|
+
total = power + command.modify_number
|
|
178
|
+
sequence = [
|
|
179
|
+
"(#{command.command.capitalize}#{Format.modifier(command.modify_number)})",
|
|
180
|
+
"2D[#{dice_list.join(',')}]=#{dice_total}",
|
|
181
|
+
"#{power}#{Format.modifier(command.modify_number)}",
|
|
182
|
+
total
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
return sequence.join(" > ")
|
|
107
186
|
end
|
|
108
187
|
|
|
109
|
-
def
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
188
|
+
def get_abyss_curse_table
|
|
189
|
+
table_result = ABYSS_CURSE_TABLE.roll(@randomizer)
|
|
190
|
+
additional =
|
|
191
|
+
case table_result.value
|
|
192
|
+
when 14 # 「差別の」における分類決定表
|
|
193
|
+
ABYSS_CURSE_CATEGORY_TABLE.roll(@randomizer).to_s
|
|
194
|
+
when 25 # 「過敏な」における属性決定表
|
|
195
|
+
ABYSS_CURSE_ATTR_TABLE.roll(@randomizer).to_s
|
|
196
|
+
end
|
|
197
|
+
final_result = [
|
|
198
|
+
table_result.to_s,
|
|
199
|
+
additional,
|
|
200
|
+
].compact
|
|
201
|
+
|
|
202
|
+
return final_result.join("\n")
|
|
117
203
|
end
|
|
118
204
|
end
|
|
119
205
|
end
|
|
@@ -28,7 +28,7 @@ module BCDice
|
|
|
28
28
|
・ボーナス表「BTx+y or BONUSx+y or TOTALx+y」 xは数値, yは技能基本値
|
|
29
29
|
INFO_MESSAGE_TEXT
|
|
30
30
|
|
|
31
|
-
register_prefix('TG
|
|
31
|
+
register_prefix('TG', '1R20', 'RT', 'Result', 'IT', 'Intimidate', 'Test', 'TT', 'Taunt', 'Trick', 'CT', 'MT', 'Maneuver', 'ODT', 'ords', 'odamage', 'DT', 'damage', 'BT', 'bonus', 'total')
|
|
32
32
|
|
|
33
33
|
def replace_text(string)
|
|
34
34
|
string = string.gsub(/Result/i, 'RT')
|
|
@@ -41,7 +41,7 @@ module BCDice
|
|
|
41
41
|
・ダメージ結果表「DTx or DAMAGEx」
|
|
42
42
|
・ロールボーナス表「BTx+y or BONUSx+y or TOTALx+y」 xは数値, yは技能基本値
|
|
43
43
|
INFO_MESSAGE_TEXT
|
|
44
|
-
register_prefix('TE
|
|
44
|
+
register_prefix('TE', 'UP', 'POS', '\d+BD', 'TG', 'RT', 'Result', 'DT', 'damage', 'BT', 'bonus', 'total', '1R20')
|
|
45
45
|
|
|
46
46
|
def eval_game_system_specific_command(command)
|
|
47
47
|
torg_check(command) ||
|
|
@@ -229,7 +229,7 @@ module BCDice
|
|
|
229
229
|
# ロールボーナス表コマンド
|
|
230
230
|
def getRollBonusDiceCommandResult(command)
|
|
231
231
|
debug("TorgEternity Roll Bonus Table Command ? ", command)
|
|
232
|
-
m = /(BT|Bonus)(\d+)(([+\-]\d+)*)/i.match(command)
|
|
232
|
+
m = /(BT|Bonus|Total)(\d+)(([+\-]\d+)*)/i.match(command)
|
|
233
233
|
unless m
|
|
234
234
|
return nil
|
|
235
235
|
end
|
|
@@ -41,7 +41,7 @@ module BCDice
|
|
|
41
41
|
NOT_CHECK_SUCCESS = -1 # 判定成功にかかわるチェックを行わない(判定失敗に関わるチェックは行う)
|
|
42
42
|
|
|
43
43
|
# ダイスボットで使用するコマンドを配列で列挙する
|
|
44
|
-
register_prefix('\d*VMF
|
|
44
|
+
register_prefix('\d*VMF')
|
|
45
45
|
|
|
46
46
|
def eval_game_system_specific_command(command)
|
|
47
47
|
m = /\A(\d+)?(VMF)(\d+)(\+(\d+))?/.match(command)
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class Cthulhu7th < 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
|
+
getFullAutoResult(command)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
include Rollable
|
|
34
|
+
|
|
35
|
+
def getFullAutoResult(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 || 0
|
|
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 += rollFullAuto(bullet_count, diff, broken_number, bonus_dice_count, stop_count, bullet_set_count_cap)
|
|
88
|
+
|
|
89
|
+
return output
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def rollFullAuto(bullet_count, diff, broken_number, dice_num, stop_count, bullet_set_count_cap)
|
|
93
|
+
output = ""
|
|
94
|
+
loopCount = 0
|
|
95
|
+
|
|
96
|
+
counts = {
|
|
97
|
+
hit_bullet: 0,
|
|
98
|
+
impale_bullet: 0,
|
|
99
|
+
bullet: bullet_count,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# 難易度変更用ループ
|
|
103
|
+
(0..3).each do |more_difficulty|
|
|
104
|
+
output += getNextDifficultyMessage(more_difficulty)
|
|
105
|
+
|
|
106
|
+
# ペナルティダイスを減らしながらロール用ループ
|
|
107
|
+
while dice_num >= BONUS_DICE_RANGE.min
|
|
108
|
+
|
|
109
|
+
loopCount += 1
|
|
110
|
+
hit_result, total, total_list = getHitResultInfos(dice_num, diff, more_difficulty)
|
|
111
|
+
output += "\n#{loopCount}回目: > #{total_list.join(', ')} > #{hit_result}"
|
|
112
|
+
|
|
113
|
+
if total >= broken_number
|
|
114
|
+
output += " ジャム"
|
|
115
|
+
return getHitResultText(output, counts)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
hit_type = getHitType(more_difficulty, hit_result)
|
|
119
|
+
hit_bullet, impale_bullet, lost_bullet = getBulletResults(counts[:bullet], hit_type, diff, bullet_set_count_cap)
|
|
120
|
+
|
|
121
|
+
output += " (#{hit_bullet}発が命中、#{impale_bullet}発が貫通)"
|
|
122
|
+
|
|
123
|
+
counts[:hit_bullet] += hit_bullet
|
|
124
|
+
counts[:impale_bullet] += impale_bullet
|
|
125
|
+
counts[:bullet] -= lost_bullet
|
|
126
|
+
|
|
127
|
+
return getHitResultText(output, counts) if counts[:bullet] <= 0
|
|
128
|
+
|
|
129
|
+
dice_num -= 1
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 指定された難易度となった場合、連射処理を途中で止める
|
|
133
|
+
if shouldStopRollFullAuto?(stop_count, more_difficulty)
|
|
134
|
+
output += "\n【指定の難易度となったので、処理を終了します。】"
|
|
135
|
+
break
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
dice_num += 1
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
return getHitResultText(output, counts)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# 連射処理を止めるべきかどうかを返す
|
|
145
|
+
# @param [String] stop_count 成功の種類
|
|
146
|
+
# @param [Integer] difficulty 難易度
|
|
147
|
+
# @return [Boolean]
|
|
148
|
+
def shouldStopRollFullAuto?(stop_count, difficulty)
|
|
149
|
+
difficulty_threshold = ROLL_FULL_AUTO_DIFFICULTY_THRESHOLD[stop_count]
|
|
150
|
+
return difficulty_threshold && difficulty >= difficulty_threshold
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def getHitResultInfos(dice_num, diff, more_difficulty)
|
|
154
|
+
total, total_list = roll_with_bonus(dice_num)
|
|
155
|
+
|
|
156
|
+
fumbleable = getFumbleable(more_difficulty)
|
|
157
|
+
hit_result = ResultLevel.from_values(total, diff, fumbleable).to_s
|
|
158
|
+
|
|
159
|
+
return hit_result, total, total_list
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def getHitResultText(output, counts)
|
|
163
|
+
return "#{output}\n> #{counts[:hit_bullet]}発が通常命中、#{counts[:impale_bullet]}発が貫通、残弾#{counts[:bullet]}発"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def getHitType(more_difficulty, hit_result)
|
|
167
|
+
successList, impaleBulletList = getSuccessListImpaleBulletList(more_difficulty)
|
|
168
|
+
|
|
169
|
+
return :hit if successList.include?(hit_result)
|
|
170
|
+
return :impale if impaleBulletList.include?(hit_result)
|
|
171
|
+
|
|
172
|
+
return ""
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def getBulletResults(bullet_count, hit_type, diff, bullet_set_count_cap)
|
|
176
|
+
bullet_set_count = getSetOfBullet(diff, bullet_set_count_cap)
|
|
177
|
+
hit_bullet_count_base = getHitBulletCountBase(diff, bullet_set_count)
|
|
178
|
+
impale_bullet_count_base = (bullet_set_count / 2.to_f)
|
|
179
|
+
|
|
180
|
+
lost_bullet_count = 0
|
|
181
|
+
hit_bullet_count = 0
|
|
182
|
+
impale_bullet_count = 0
|
|
183
|
+
|
|
184
|
+
if !isLastBulletTurn(bullet_count, bullet_set_count)
|
|
185
|
+
|
|
186
|
+
case hit_type
|
|
187
|
+
when :hit
|
|
188
|
+
hit_bullet_count = hit_bullet_count_base # 通常命中した弾数の計算
|
|
189
|
+
|
|
190
|
+
when :impale
|
|
191
|
+
impale_bullet_count = impale_bullet_count_base.floor # 貫通した弾数の計算
|
|
192
|
+
hit_bullet_count = impale_bullet_count_base.ceil
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
lost_bullet_count = bullet_set_count
|
|
196
|
+
|
|
197
|
+
else
|
|
198
|
+
|
|
199
|
+
case hit_type
|
|
200
|
+
when :hit
|
|
201
|
+
hit_bullet_count = getLastHitBulletCount(bullet_count)
|
|
202
|
+
|
|
203
|
+
when :impale
|
|
204
|
+
impale_bullet_count = getLastHitBulletCount(bullet_count)
|
|
205
|
+
hit_bullet_count = bullet_count - impale_bullet_count
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
lost_bullet_count = bullet_count
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
return hit_bullet_count, impale_bullet_count, lost_bullet_count
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def getSuccessListImpaleBulletList(more_difficulty)
|
|
215
|
+
successList = []
|
|
216
|
+
impaleBulletList = []
|
|
217
|
+
|
|
218
|
+
case more_difficulty
|
|
219
|
+
when 0
|
|
220
|
+
successList = ["ハード成功", "レギュラー成功"]
|
|
221
|
+
impaleBulletList = ["クリティカル", "イクストリーム成功"]
|
|
222
|
+
when 1
|
|
223
|
+
successList = ["ハード成功"]
|
|
224
|
+
impaleBulletList = ["クリティカル", "イクストリーム成功"]
|
|
225
|
+
when 2
|
|
226
|
+
successList = []
|
|
227
|
+
impaleBulletList = ["クリティカル", "イクストリーム成功"]
|
|
228
|
+
when 3
|
|
229
|
+
successList = ["クリティカル"]
|
|
230
|
+
impaleBulletList = []
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
return successList, impaleBulletList
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def getNextDifficultyMessage(more_difficulty)
|
|
237
|
+
case more_difficulty
|
|
238
|
+
when 1
|
|
239
|
+
return "\n【難易度がハードに変更】"
|
|
240
|
+
when 2
|
|
241
|
+
return "\n【難易度がイクストリームに変更】"
|
|
242
|
+
when 3
|
|
243
|
+
return "\n【難易度がクリティカルに変更】"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
return ""
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def getSetOfBullet(diff, bullet_set_count_cap)
|
|
250
|
+
bullet_set_count = diff / 10
|
|
251
|
+
|
|
252
|
+
if bullet_set_count_cap < bullet_set_count
|
|
253
|
+
bullet_set_count = bullet_set_count_cap
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
if (diff >= 1) && (diff < 30)
|
|
257
|
+
bullet_set_count = 3 # 技能値が29以下での最低値保障処理
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
return bullet_set_count
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def getHitBulletCountBase(diff, bullet_set_count)
|
|
264
|
+
hit_bullet_count_base = (bullet_set_count / 2)
|
|
265
|
+
|
|
266
|
+
if (diff >= 1) && (diff < 30)
|
|
267
|
+
hit_bullet_count_base = 1 # 技能値29以下での最低値保障
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
return hit_bullet_count_base
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def isLastBulletTurn(bullet_count, bullet_set_count)
|
|
274
|
+
((bullet_count - bullet_set_count) < 0)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def getLastHitBulletCount(bullet_count)
|
|
278
|
+
# 残弾1での最低値保障処理
|
|
279
|
+
if bullet_count == 1
|
|
280
|
+
return 1
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
count = (bullet_count / 2.to_f).floor
|
|
284
|
+
return count
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def getFumbleable(more_difficulty)
|
|
288
|
+
# 成功が49以下の出目のみとなるため、ファンブル値は上昇
|
|
289
|
+
return (more_difficulty >= 1)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|