bcdice 3.1.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +78 -1
- data/README.md +1 -1
- data/i18n/MagicaLogia/zh_hans.yml +564 -0
- data/i18n/StellarKnights/ja_jp.yml +498 -0
- data/i18n/StellarKnights/ko_kr.yml +498 -0
- data/i18n/zh_hans.yml +7 -0
- data/lib/bcdice/command/parsed.rb +11 -3
- data/lib/bcdice/command/parser.rb +179 -100
- data/lib/bcdice/common_command/add_dice.rb +1 -1
- data/lib/bcdice/common_command/barabara_dice/node.rb +2 -2
- data/lib/bcdice/common_command/barabara_dice/result.rb +6 -0
- data/lib/bcdice/common_command/calc.rb +1 -1
- data/lib/bcdice/dice_table.rb +2 -0
- data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
- data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
- data/lib/bcdice/dice_table/sai_fic_skill_table.rb +1 -1
- data/lib/bcdice/game_system.rb +6 -0
- data/lib/bcdice/game_system/AceKillerGene.rb +1 -1
- data/lib/bcdice/game_system/Ainecadette.rb +68 -0
- data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
- data/lib/bcdice/game_system/Alsetto.rb +1 -1
- data/lib/bcdice/game_system/AlterRaise.rb +2 -2
- data/lib/bcdice/game_system/Amadeus.rb +110 -93
- data/lib/bcdice/game_system/AngelGear.rb +2 -2
- data/lib/bcdice/game_system/AnimaAnimus.rb +16 -9
- data/lib/bcdice/game_system/Arianrhod.rb +6 -8
- data/lib/bcdice/game_system/Avandner.rb +1 -1
- data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
- data/lib/bcdice/game_system/BattleTech.rb +109 -28
- data/lib/bcdice/game_system/BeastBindTrinity.rb +28 -12
- data/lib/bcdice/game_system/BeginningIdol.rb +5 -5
- data/lib/bcdice/game_system/BeginningIdol_Korean.rb +5 -5
- data/lib/bcdice/game_system/BladeOfArcana.rb +1 -1
- data/lib/bcdice/game_system/BlindMythos.rb +39 -38
- data/lib/bcdice/game_system/BloodCrusade.rb +6 -7
- data/lib/bcdice/game_system/BloodMoon.rb +9 -8
- data/lib/bcdice/game_system/CardRanker.rb +8 -7
- data/lib/bcdice/game_system/ChaosFlare.rb +21 -15
- data/lib/bcdice/game_system/Chill.rb +10 -10
- data/lib/bcdice/game_system/Chill3.rb +9 -9
- data/lib/bcdice/game_system/CodeLayerd.rb +39 -39
- data/lib/bcdice/game_system/ColossalHunter.rb +34 -47
- data/lib/bcdice/game_system/CrashWorld.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu7th.rb +48 -10
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +2 -2
- data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +2 -2
- data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +1 -1
- data/lib/bcdice/game_system/Cthulhu_Korean.rb +1 -1
- data/lib/bcdice/game_system/DarkBlaze.rb +0 -11
- data/lib/bcdice/game_system/DarkDaysDrive.rb +8 -7
- data/lib/bcdice/game_system/DeadlineHeroes.rb +11 -10
- data/lib/bcdice/game_system/DemonParasite.rb +5 -13
- data/lib/bcdice/game_system/DesperateRun.rb +1 -1
- data/lib/bcdice/game_system/DoubleCross.rb +3 -1
- data/lib/bcdice/game_system/Dracurouge.rb +1 -1
- data/lib/bcdice/game_system/EclipsePhase.rb +14 -14
- data/lib/bcdice/game_system/Elric.rb +18 -14
- data/lib/bcdice/game_system/Elysion.rb +1 -1
- data/lib/bcdice/game_system/EmbryoMachine.rb +9 -8
- data/lib/bcdice/game_system/Emoklore.rb +25 -20
- data/lib/bcdice/game_system/Fiasco.rb +1 -1
- data/lib/bcdice/game_system/FilledWith.rb +205 -1272
- data/lib/bcdice/game_system/FutariSousa.rb +12 -10
- data/lib/bcdice/game_system/GURPS.rb +17 -28
- data/lib/bcdice/game_system/Garako.rb +1 -1
- data/lib/bcdice/game_system/GardenOrder.rb +12 -7
- data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
- data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
- data/lib/bcdice/game_system/Gorilla.rb +2 -8
- data/lib/bcdice/game_system/GranCrest.rb +18 -11
- data/lib/bcdice/game_system/Gundog.rb +9 -8
- data/lib/bcdice/game_system/GundogRevised.rb +10 -9
- data/lib/bcdice/game_system/GundogZero.rb +1 -1
- data/lib/bcdice/game_system/GurpsFW.rb +16 -16
- data/lib/bcdice/game_system/HarnMaster.rb +19 -26
- data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
- data/lib/bcdice/game_system/Hieizan.rb +12 -21
- data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
- data/lib/bcdice/game_system/HuntersMoon.rb +5 -10
- data/lib/bcdice/game_system/InfiniteFantasia.rb +19 -17
- data/lib/bcdice/game_system/Insane.rb +13 -20
- data/lib/bcdice/game_system/IthaWenUa.rb +8 -15
- data/lib/bcdice/game_system/JamesBond.rb +10 -10
- data/lib/bcdice/game_system/JekyllAndHyde.rb +1 -1
- data/lib/bcdice/game_system/Kamigakari.rb +1 -1
- data/lib/bcdice/game_system/KanColle.rb +4 -9
- data/lib/bcdice/game_system/KemonoNoMori.rb +26 -39
- data/lib/bcdice/game_system/KillDeathBusiness.rb +7 -15
- data/lib/bcdice/game_system/KurayamiCrying.rb +141 -2
- data/lib/bcdice/game_system/LiveraDoll.rb +254 -304
- data/lib/bcdice/game_system/LogHorizon.rb +13 -10
- data/lib/bcdice/game_system/MagicaLogia_SimplifiedChinese.rb +66 -0
- data/lib/bcdice/game_system/MeikyuDays.rb +10 -8
- data/lib/bcdice/game_system/MeikyuKingdom.rb +26 -26
- data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +5 -4
- data/lib/bcdice/game_system/MetalHead.rb +12 -22
- data/lib/bcdice/game_system/MetalHeadExtream.rb +5 -5
- data/lib/bcdice/game_system/MonotoneMuseum.rb +8 -6
- data/lib/bcdice/game_system/Nechronica.rb +63 -90
- data/lib/bcdice/game_system/NinjaSlayer.rb +6 -7
- data/lib/bcdice/game_system/NjslyrBattle.rb +8 -11
- data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
- data/lib/bcdice/game_system/Paradiso.rb +3 -3
- data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
- data/lib/bcdice/game_system/Peekaboo.rb +4 -9
- data/lib/bcdice/game_system/Pendragon.rb +7 -7
- data/lib/bcdice/game_system/PhantasmAdventure.rb +8 -8
- data/lib/bcdice/game_system/Postman.rb +1 -1
- data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
- data/lib/bcdice/game_system/Raisondetre.rb +2 -2
- data/lib/bcdice/game_system/Revulture.rb +123 -0
- data/lib/bcdice/game_system/RuneQuest.rb +8 -8
- data/lib/bcdice/game_system/Ryutama.rb +1 -1
- data/lib/bcdice/game_system/SRS.rb +17 -16
- data/lib/bcdice/game_system/SamsaraBallad.rb +38 -11
- data/lib/bcdice/game_system/Satasupe.rb +32 -32
- data/lib/bcdice/game_system/ScreamHighSchool.rb +5 -5
- data/lib/bcdice/game_system/SharedFantasia.rb +19 -23
- data/lib/bcdice/game_system/ShinobiGami.rb +14 -6
- data/lib/bcdice/game_system/Skynauts.rb +103 -142
- data/lib/bcdice/game_system/SkynautsBouken.rb +228 -0
- data/lib/bcdice/game_system/StarryDolls.rb +318 -0
- data/lib/bcdice/game_system/SteamPunkers.rb +11 -6
- data/lib/bcdice/game_system/StellarKnights.rb +85 -706
- data/lib/bcdice/game_system/StellarKnights_Korean.rb +79 -0
- data/lib/bcdice/game_system/SterileLife.rb +2 -3
- data/lib/bcdice/game_system/StrangerOfSwordCity.rb +1 -1
- data/lib/bcdice/game_system/StratoShout.rb +8 -16
- data/lib/bcdice/game_system/Strave.rb +1 -1
- data/lib/bcdice/game_system/SwordWorld.rb +16 -7
- data/lib/bcdice/game_system/SwordWorld2_0.rb +2 -2
- data/lib/bcdice/game_system/SwordWorld2_5.rb +2 -2
- data/lib/bcdice/game_system/TherapieSein.rb +1 -1
- data/lib/bcdice/game_system/TokumeiTenkousei.rb +4 -3
- data/lib/bcdice/game_system/TokyoGhostResearch.rb +1 -1
- data/lib/bcdice/game_system/TrinitySeven.rb +279 -280
- data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
- data/lib/bcdice/game_system/Utakaze.rb +53 -48
- data/lib/bcdice/game_system/Villaciel.rb +1 -1
- data/lib/bcdice/game_system/WARPS.rb +11 -9
- data/lib/bcdice/game_system/WaresBlade.rb +4 -9
- data/lib/bcdice/game_system/Warhammer.rb +15 -6
- data/lib/bcdice/game_system/Warhammer4.rb +15 -11
- data/lib/bcdice/game_system/WitchQuest.rb +1 -1
- data/lib/bcdice/game_system/YankeeYogSothoth.rb +4 -9
- data/lib/bcdice/game_system/Yggdrasill.rb +1 -1
- data/lib/bcdice/game_system/ZettaiReido.rb +20 -25
- data/lib/bcdice/game_system/filled_with/enemy_data_tables.rb +322 -0
- data/lib/bcdice/game_system/filled_with/event_tables.rb +392 -0
- data/lib/bcdice/game_system/filled_with/tresure_tables.rb +179 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +1 -1
- data/lib/bcdice/game_system/sword_world/rating_parsed.rb +4 -4
- data/lib/bcdice/game_system/sword_world/rating_parser.rb +1 -1
- data/lib/bcdice/game_system/sword_world/transcendent_test.rb +26 -8
- data/lib/bcdice/repl.rb +1 -1
- data/lib/bcdice/result.rb +26 -0
- data/lib/bcdice/version.rb +1 -1
- metadata +18 -4
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'bcdice/base'
|
4
|
+
|
3
5
|
module BCDice
|
4
6
|
module GameSystem
|
5
7
|
class SamsaraBallad < Base
|
@@ -59,38 +61,63 @@ module BCDice
|
|
59
61
|
total = 100 if total == 0
|
60
62
|
end
|
61
63
|
|
62
|
-
|
64
|
+
result = compare(total, cmd)
|
65
|
+
|
66
|
+
result_str =
|
67
|
+
if result.failure?
|
68
|
+
"失敗"
|
69
|
+
elsif result.success?
|
70
|
+
"成功"
|
71
|
+
end
|
72
|
+
|
73
|
+
additional_str =
|
74
|
+
if result.fumble?
|
75
|
+
"ファンブル"
|
76
|
+
elsif result.critical?
|
77
|
+
"クリティカル"
|
78
|
+
end
|
63
79
|
|
64
80
|
sequence = [
|
65
81
|
"(D100#{cmd.cmp_op}#{cmd.target_number})",
|
66
82
|
places_text,
|
67
83
|
total.to_s,
|
68
|
-
|
84
|
+
result_str,
|
85
|
+
additional_str,
|
69
86
|
].compact
|
70
87
|
|
71
|
-
|
88
|
+
result.text = sequence.join(" > ")
|
89
|
+
|
90
|
+
return result
|
72
91
|
end
|
73
92
|
|
74
93
|
private
|
75
94
|
|
76
|
-
# @return [
|
77
|
-
# @return [nil]
|
95
|
+
# @return [Result]
|
78
96
|
def compare(total, cmd)
|
79
97
|
if [:<=, :<].include?(cmd.cmp_op)
|
80
98
|
if !total.send(cmd.cmp_op, cmd.target_number)
|
81
|
-
|
99
|
+
Result.failure(nil)
|
82
100
|
elsif fumble_?(total, cmd.fumble)
|
83
|
-
|
101
|
+
Result.new.tap do |r|
|
102
|
+
r.success = true
|
103
|
+
r.fumble = true
|
104
|
+
end
|
84
105
|
elsif critical_?(total, cmd.critical)
|
85
|
-
|
106
|
+
Result.critical(nil)
|
86
107
|
else
|
87
|
-
|
108
|
+
Result.success(nil)
|
88
109
|
end
|
89
110
|
elsif fumble_?(total, cmd.fumble)
|
90
111
|
# ファンブル優先
|
91
|
-
|
112
|
+
Result.new.tap do |r|
|
113
|
+
r.fumble = true
|
114
|
+
end
|
92
115
|
elsif critical_?(total, cmd.critical)
|
93
|
-
|
116
|
+
Result.new.tap do |r|
|
117
|
+
r.critical = true
|
118
|
+
end
|
119
|
+
else
|
120
|
+
Result.new
|
94
121
|
end
|
95
122
|
end
|
96
123
|
|
@@ -49,7 +49,7 @@ module BCDice
|
|
49
49
|
・D66ダイスあり
|
50
50
|
INFO_MESSAGE_TEXT
|
51
51
|
|
52
|
-
register_prefix('\d+R', 'SR
|
52
|
+
register_prefix('\d+R', 'SR', 'TAGT', 'GETSST', 'NPCT', TABLES.keys, ALIASES.keys)
|
53
53
|
|
54
54
|
CREATE_ARMS_STRUCT = Struct.new(:base_parts, :accessory_parts, :parts_effect, :hit, :damage, :life, :kutibeni, :kiba, :abilities)
|
55
55
|
|
@@ -64,7 +64,7 @@ module BCDice
|
|
64
64
|
debug("eval_game_system_specific_command begin string", command)
|
65
65
|
|
66
66
|
result = checkRoll(command)
|
67
|
-
return result unless result.
|
67
|
+
return result unless result.nil?
|
68
68
|
|
69
69
|
debug("判定ロールではなかった")
|
70
70
|
|
@@ -81,13 +81,13 @@ module BCDice
|
|
81
81
|
debug("checkRoll begin string", string)
|
82
82
|
|
83
83
|
m = /^(\d+)R>=(\d+)(\[(\d+)?(,|,\d+)?(,\d+(S)?)?\])?$/i.match(string)
|
84
|
-
return
|
84
|
+
return nil unless m
|
85
85
|
|
86
86
|
roll_times = m[1].to_i
|
87
87
|
target = m[2].to_i
|
88
88
|
params = m[3]
|
89
89
|
|
90
|
-
min_suc, fumble, critical,
|
90
|
+
min_suc, fumble, critical, is_critical_stop = get_roll_params(params)
|
91
91
|
|
92
92
|
result = ""
|
93
93
|
|
@@ -104,8 +104,8 @@ module BCDice
|
|
104
104
|
end
|
105
105
|
|
106
106
|
if fumble >= 6
|
107
|
-
result += "#{
|
108
|
-
return result
|
107
|
+
result += "#{get_judge_info(target, fumble, critical)} > ファンブル率が6を超えたため自動失敗!"
|
108
|
+
return Result.failure(result)
|
109
109
|
end
|
110
110
|
|
111
111
|
if target < 5
|
@@ -113,23 +113,30 @@ module BCDice
|
|
113
113
|
target = 5
|
114
114
|
end
|
115
115
|
|
116
|
-
dice_str, total_suc,
|
116
|
+
dice_str, total_suc, is_critical, is_fumble = check_roll_loop(roll_times, min_suc, target, critical, fumble, is_critical_stop)
|
117
117
|
|
118
|
-
result += "#{
|
118
|
+
result += "#{get_judge_info(target, fumble, critical)} > #{dice_str} > 成功度#{total_suc}"
|
119
119
|
|
120
|
-
if
|
120
|
+
if is_fumble
|
121
121
|
result += " > ファンブル"
|
122
122
|
end
|
123
123
|
|
124
|
-
if
|
124
|
+
if is_critical && (total_suc > 0)
|
125
125
|
result += " > 必殺発動可能!"
|
126
126
|
end
|
127
127
|
|
128
128
|
debug('checkRoll result result', result)
|
129
|
-
|
129
|
+
|
130
|
+
return Result.new.tap do |r|
|
131
|
+
r.text = result
|
132
|
+
r.success = !is_fumble && min_suc > 0 && total_suc >= min_suc
|
133
|
+
r.failure = is_fumble
|
134
|
+
r.critical = is_critical
|
135
|
+
r.fumble = is_fumble
|
136
|
+
end
|
130
137
|
end
|
131
138
|
|
132
|
-
def
|
139
|
+
def get_roll_params(params)
|
133
140
|
min_suc = 0
|
134
141
|
fumble = 1
|
135
142
|
critical = 13
|
@@ -154,19 +161,14 @@ module BCDice
|
|
154
161
|
return min_suc, fumble, critical, isCriticalStop
|
155
162
|
end
|
156
163
|
|
157
|
-
def
|
158
|
-
"【難易度#{target}、ファンブル率#{fumble}
|
164
|
+
def get_judge_info(target, fumble, critical)
|
165
|
+
return "【難易度#{target}、ファンブル率#{fumble}、必殺#{critical == 13 ? 'なし' : critical.to_s}】"
|
159
166
|
end
|
160
167
|
|
161
|
-
def
|
162
|
-
criticalString = (critical == 13 ? "なし" : critical.to_s)
|
163
|
-
return "、必殺#{criticalString}"
|
164
|
-
end
|
165
|
-
|
166
|
-
def checkRollLoop(roll_times, min_suc, target, critical, fumble, isCriticalStop)
|
168
|
+
def check_roll_loop(roll_times, min_suc, target, critical, fumble, is_critical_stop)
|
167
169
|
dice_str = ''
|
168
|
-
|
169
|
-
|
170
|
+
is_fumble = false
|
171
|
+
is_critical = false
|
170
172
|
total_suc = 0
|
171
173
|
|
172
174
|
roll_times.times do |_i|
|
@@ -193,38 +195,36 @@ module BCDice
|
|
193
195
|
total_suc += dice_suc
|
194
196
|
|
195
197
|
if critical <= d1 + d2
|
196
|
-
|
198
|
+
is_critical = true
|
197
199
|
dice_str += "『必殺!』"
|
198
200
|
end
|
199
201
|
|
200
202
|
if (d1 == d2) && (d1 <= fumble) # ファンブルの確認
|
201
|
-
|
202
|
-
|
203
|
+
is_fumble = true
|
204
|
+
is_critical = false
|
203
205
|
break
|
204
206
|
end
|
205
207
|
|
206
|
-
if
|
208
|
+
if is_critical && is_critical_stop # 必殺止めの確認
|
207
209
|
break
|
208
210
|
end
|
209
211
|
end
|
210
212
|
|
211
|
-
return dice_str, total_suc,
|
213
|
+
return dice_str, total_suc, is_critical, is_fumble
|
212
214
|
end
|
213
215
|
|
214
216
|
def check_seigou(string)
|
215
217
|
debug("check_seigou begin string", string)
|
216
218
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
target = m[1].to_i
|
221
|
-
sr_parser = Command::Parser.new(/SR\d+/i, round_type: round_type)
|
219
|
+
sr_parser = Command::Parser.new("SR", round_type: round_type)
|
220
|
+
.has_suffix_number
|
222
221
|
.restrict_cmp_op_to(nil)
|
223
222
|
cmd = sr_parser.parse(string)
|
224
223
|
return '' unless cmd
|
225
224
|
|
226
225
|
dice = @randomizer.roll_sum(2, 6)
|
227
226
|
diceTotal = dice + cmd.modify_number
|
227
|
+
target = cmd.suffix_number
|
228
228
|
|
229
229
|
seigou = if target < diceTotal
|
230
230
|
"「激」"
|
@@ -37,8 +37,8 @@ module BCDice
|
|
37
37
|
INFO_MESSAGE_TEXT
|
38
38
|
|
39
39
|
register_prefix(
|
40
|
-
'(SH|SHS)
|
41
|
-
'(EM|TR|FE)
|
40
|
+
'(SH|SHS)',
|
41
|
+
'(EM|TR|FE)',
|
42
42
|
'DC(SL|BL|IM|BR|RF|EL).+'
|
43
43
|
)
|
44
44
|
|
@@ -73,13 +73,13 @@ module BCDice
|
|
73
73
|
|
74
74
|
dice_value = @randomizer.roll_once(100)
|
75
75
|
result = get_check_result(dice_value, success_rate, critical_border, fumble_border)
|
76
|
-
title, supplementary = get_supplementary(command_type, result)
|
76
|
+
title, supplementary = get_supplementary(command_type, result.text)
|
77
77
|
unless supplementary.empty?
|
78
78
|
supplementary = "(#{supplementary})"
|
79
79
|
end
|
80
80
|
|
81
|
-
text = "#{title}判定 D100<=#{success_rate}@#{critical_border} > #{dice_value} > #{result}#{supplementary}"
|
82
|
-
return
|
81
|
+
result.text = "#{title}判定 D100<=#{success_rate}@#{critical_border} > #{dice_value} > #{result.text}#{supplementary}"
|
82
|
+
return result
|
83
83
|
end
|
84
84
|
|
85
85
|
def get_supplementary(command_type, result)
|
@@ -24,11 +24,12 @@ module BCDice
|
|
24
24
|
register_prefix('SF', 'ST')
|
25
25
|
|
26
26
|
def change_text(string)
|
27
|
-
string.gsub(/
|
27
|
+
string.gsub(/S[FT]/i, "2D6")
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
return
|
30
|
+
def result_2d6(total, dice_total, _dice_list, cmp_op, target)
|
31
|
+
return Result.nothing if target == '?'
|
32
|
+
return nil unless [:>=, :>].include?(cmp_op)
|
32
33
|
|
33
34
|
critical = false
|
34
35
|
fumble = false
|
@@ -39,28 +40,23 @@ module BCDice
|
|
39
40
|
fumble = true
|
40
41
|
end
|
41
42
|
|
42
|
-
totalValueBonus = 0
|
43
|
-
if cmp_op == :>=
|
44
|
-
totalValueBonus = 1
|
45
|
-
end
|
43
|
+
totalValueBonus = (cmp_op == :>= ? 1 : 0)
|
46
44
|
|
47
|
-
if
|
48
|
-
if
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
if (total + totalValueBonus) > target
|
46
|
+
if critical
|
47
|
+
Result.critical("自動成功(劇的成功)")
|
48
|
+
elsif fumble
|
49
|
+
Result.failure("自動失敗")
|
50
|
+
else
|
51
|
+
Result.success("成功")
|
52
|
+
end
|
53
|
+
else
|
54
|
+
if critical
|
55
|
+
Result.success("自動成功")
|
56
|
+
elsif fumble
|
57
|
+
Result.fumble("自動失敗(致命的失敗)")
|
56
58
|
else
|
57
|
-
|
58
|
-
return " > 自動成功"
|
59
|
-
elsif fumble
|
60
|
-
return " > 自動失敗(致命的失敗)"
|
61
|
-
else
|
62
|
-
return " > 失敗"
|
63
|
-
end
|
59
|
+
Result.failure("失敗")
|
64
60
|
end
|
65
61
|
end
|
66
62
|
end
|
@@ -16,12 +16,13 @@ module BCDice
|
|
16
16
|
|
17
17
|
# ダイスボットの使い方
|
18
18
|
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
|
19
|
-
・行為判定
|
20
|
-
2D6
|
19
|
+
・行為判定 nSG@s#f>=x
|
20
|
+
2D6の行為判定を行う。ダイス数が指定された場合、大きい出目2個を採用する。
|
21
|
+
n: ダイス数 (省略時 2)
|
21
22
|
s: スペシャル値 (省略時 12)
|
22
23
|
f: ファンブル値 (省略時 2)
|
23
24
|
x: 目標値 (省略可)
|
24
|
-
例)SG, SG@11, SG@11#3, SG#3>=7
|
25
|
+
例)SG, SG@11, SG@11#3, SG#3>=7, 3SG>=7
|
25
26
|
・各種表
|
26
27
|
・(無印)シーン表 ST/ファンブル表 FT/感情表 ET
|
27
28
|
/変調表 WT/戦場表 BT/異形表 MT
|
@@ -68,7 +69,7 @@ module BCDice
|
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
|
-
register_prefix(
|
72
|
+
register_prefix('\d*SG')
|
72
73
|
|
73
74
|
def eval_game_system_specific_command(command)
|
74
75
|
result = action_roll(command) || roll_tables(command, TABLES) || RTT.roll_command(@randomizer, command)
|
@@ -94,17 +95,23 @@ module BCDice
|
|
94
95
|
private
|
95
96
|
|
96
97
|
def action_roll(command)
|
97
|
-
parser = Command::Parser.new(
|
98
|
+
parser = Command::Parser.new(/\d*SG/, round_type: round_type)
|
98
99
|
.restrict_cmp_op_to(:>=, nil)
|
99
100
|
.enable_critical
|
100
101
|
.enable_fumble
|
101
102
|
cmd = parser.parse(command)
|
102
103
|
return nil unless cmd
|
103
104
|
|
105
|
+
times = cmd.command.start_with?(/\d/) ? cmd.command.to_i : 2
|
106
|
+
return nil if times <= 1
|
107
|
+
|
104
108
|
cmd.critical ||= 12
|
105
109
|
cmd.fumble ||= 2
|
106
110
|
|
107
|
-
|
111
|
+
dice_list_full = @randomizer.roll_barabara(times, 6).sort
|
112
|
+
dice_list_full_str = "[#{dice_list_full.join(',')}]" if times > 2
|
113
|
+
|
114
|
+
dice_list = dice_list_full[-2, 2]
|
108
115
|
dice_total = dice_list.sum()
|
109
116
|
total = dice_total + cmd.modify_number
|
110
117
|
|
@@ -123,6 +130,7 @@ module BCDice
|
|
123
130
|
|
124
131
|
sequence = [
|
125
132
|
"(#{cmd.to_s(:after_modify_number)})",
|
133
|
+
dice_list_full_str,
|
126
134
|
"#{dice_total}[#{dice_list.join(',')}]#{Format.modifier(cmd.modify_number)}",
|
127
135
|
total,
|
128
136
|
result.text
|
@@ -7,10 +7,10 @@ module BCDice
|
|
7
7
|
ID = 'Skynauts'
|
8
8
|
|
9
9
|
# ゲームシステム名
|
10
|
-
NAME = '
|
10
|
+
NAME = '歯車の塔の探空士(六畳間幻想空間)'
|
11
11
|
|
12
12
|
# ゲームシステム名の読みがな
|
13
|
-
SORT_KEY = '
|
13
|
+
SORT_KEY = 'はくるまのとうのすかいのおつ'
|
14
14
|
|
15
15
|
# ダイスボットの使い方
|
16
16
|
HELP_MESSAGE = <<~MESSAGETEXT
|
@@ -43,72 +43,46 @@ module BCDice
|
|
43
43
|
debug("\n=======================================\n")
|
44
44
|
debug("eval_game_system_specific_command command", command)
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
return result unless result.nil?
|
49
|
-
|
50
|
-
# 航行チェック
|
51
|
-
result = navigationResult(command)
|
52
|
-
return result unless result.nil?
|
53
|
-
|
54
|
-
# ダメージチェック
|
55
|
-
result = getFireResult(command)
|
56
|
-
return result unless result.nil?
|
57
|
-
|
58
|
-
# 砲撃判定+ダメージチェック
|
59
|
-
result = getBomberResult(command)
|
60
|
-
return result unless result.nil?
|
61
|
-
|
62
|
-
# 回避運動(操舵判定含む)
|
63
|
-
result = getAvoidResult(command)
|
64
|
-
return result unless result.nil?
|
65
|
-
|
66
|
-
debug("rollCommand result")
|
67
|
-
return nil
|
46
|
+
return get_judge_result(command) || navigation_result(command) || get_fire_result(command) ||
|
47
|
+
get_bomb_result(command) || get_avoid_result(command)
|
68
48
|
end
|
69
49
|
|
70
|
-
|
50
|
+
private
|
51
|
+
|
52
|
+
def get_judge_result(command)
|
71
53
|
return nil unless (m = (/^2D6<=(\d)$/i.match(command) || /^SN(\d*)$/i.match(command)))
|
72
54
|
|
73
|
-
debug("====
|
55
|
+
debug("====get_judge_result====")
|
74
56
|
|
75
57
|
target = m[1].empty? ? 7 : m[1].to_i # 目標値。省略時は7
|
76
58
|
debug("目標値", target)
|
77
59
|
|
78
60
|
dice_list = @randomizer.roll_barabara(2, 6)
|
79
61
|
total = dice_list.sum()
|
80
|
-
|
81
|
-
|
62
|
+
text = "(2D6<=#{target}) > #{total}[#{dice_list.join(',')}] > #{total}"
|
82
63
|
if total <= 2
|
83
|
-
|
64
|
+
Result.fumble(text + " > ファンブル")
|
84
65
|
elsif total <= target
|
85
|
-
|
66
|
+
Result.success(text + " > 成功")
|
86
67
|
else
|
87
|
-
|
68
|
+
Result.failure(text + " > 失敗")
|
88
69
|
end
|
89
|
-
|
90
|
-
text = "(2D6<=#{target}) > #{total}[#{diceText}] > #{total} > #{result}"
|
91
|
-
|
92
|
-
return text
|
93
70
|
end
|
94
71
|
|
95
|
-
def
|
72
|
+
def navigation_result(command)
|
96
73
|
return nil unless (m = /^NV(\+(\d+))?$/.match(command))
|
97
74
|
|
98
|
-
debug("====
|
75
|
+
debug("====navigation_result====")
|
99
76
|
|
100
77
|
bonus = m[2].to_i # 〈操舵室〉の修正。GMの任意修正にも対応できるように(マイナスは無視)
|
101
78
|
debug("移動修正", bonus)
|
102
79
|
|
103
80
|
total = @randomizer.roll_once(6)
|
104
|
-
|
105
|
-
movePoint =
|
81
|
+
move_point_base = (total / 2) <= 0 ? 1 : (total / 2)
|
82
|
+
movePoint = move_point_base + bonus
|
106
83
|
debug("移動エリア数", movePoint)
|
107
84
|
|
108
|
-
|
109
|
-
text += "#{movePointBase}+#{bonus} > #{movePoint}エリア進む"
|
110
|
-
|
111
|
-
return text
|
85
|
+
Result.new("航行チェック(最低1) (1D6/2+#{bonus}) > #{total} /2+#{bonus} > #{move_point_base}+#{bonus} > #{movePoint}エリア進む")
|
112
86
|
end
|
113
87
|
|
114
88
|
DIRECTION_INFOS = {
|
@@ -123,201 +97,188 @@ module BCDice
|
|
123
97
|
9 => {name: "右上", position_diff: {x: +1, y: -1}},
|
124
98
|
}.freeze
|
125
99
|
|
126
|
-
def
|
100
|
+
def get_direction_info(direction, key, default_value = nil)
|
127
101
|
info = DIRECTION_INFOS[direction.to_i]
|
128
|
-
return
|
102
|
+
return default_value if info.nil?
|
129
103
|
|
130
104
|
return info[key]
|
131
105
|
end
|
132
106
|
|
133
|
-
def
|
134
|
-
return nil unless (m = %r{^D([12346789]*)(\[.+\])*/(\d
|
107
|
+
def get_fire_result(command)
|
108
|
+
return nil unless (m = %r{^D([12346789]*)(\[.+\])*/(\d{1,2})(@([2468]))?$}.match(command))
|
135
109
|
|
136
|
-
debug("====
|
110
|
+
debug("====get_fire_result====")
|
137
111
|
|
138
|
-
|
139
|
-
|
112
|
+
fire_count = m[3].to_i # 砲撃回数
|
113
|
+
fire_range = m[1].to_s # 砲撃範囲
|
140
114
|
ballistics = m[5].to_i # 《弾道学》
|
141
|
-
debug("
|
142
|
-
debug("
|
115
|
+
debug("fire_count", fire_count)
|
116
|
+
debug("fire_range", fire_range)
|
143
117
|
debug("ballistics", ballistics)
|
144
118
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
firePoint = getFirePoint(fireRange, fireCount) # 着弾座標取得(3次元配列)
|
149
|
-
fireText = getFirePointText(firePoint, fireCount) # 表示用文字列作成
|
119
|
+
fire_point = get_fire_point(fire_range, fire_count) # 着弾座標取得(3次元配列)
|
120
|
+
result = [command, get_fire_point_text(fire_point, fire_count).text] # 表示用文字列作成
|
150
121
|
|
151
122
|
if ballistics != 0 # 《弾道学》有
|
152
|
-
|
153
|
-
|
154
|
-
fireText += "\n > "
|
155
|
-
fireText += getFirePointText(firePoint, fireCount, ballistics)
|
123
|
+
result << "《弾道学》:#{get_direction_info(ballistics, :name, '')}\n"
|
124
|
+
result << get_fire_point_text(fire_point, fire_count, ballistics).text
|
156
125
|
end
|
157
|
-
|
158
|
-
text = "#{command} > #{fireText}"
|
159
|
-
|
160
|
-
return text
|
126
|
+
Result.new(result.join(" > "))
|
161
127
|
end
|
162
128
|
|
163
|
-
def
|
164
|
-
debug("====
|
129
|
+
def get_fire_point(fire_range, fire_count)
|
130
|
+
debug("====get_fire_point====")
|
165
131
|
|
166
|
-
|
132
|
+
fire_point = []
|
167
133
|
|
168
|
-
|
134
|
+
fire_count.times do |count|
|
169
135
|
debug("\n砲撃回数", count + 1)
|
170
136
|
|
171
|
-
|
137
|
+
fire_point << []
|
172
138
|
|
173
|
-
|
174
|
-
|
175
|
-
position = [
|
139
|
+
y_pos = @randomizer.roll_once(6) # 縦
|
140
|
+
x_pos = @randomizer.roll_sum(2, 6) # 横
|
141
|
+
position = [x_pos, y_pos]
|
176
142
|
|
177
|
-
|
143
|
+
fire_point[-1] << position
|
178
144
|
|
179
|
-
debug("着弾点",
|
145
|
+
debug("着弾点", fire_point)
|
180
146
|
|
181
|
-
|
182
|
-
debug("範囲",
|
147
|
+
fire_range.chars do |range_text|
|
148
|
+
debug("範囲", range_text)
|
183
149
|
|
184
|
-
position_diff =
|
185
|
-
position = [
|
150
|
+
position_diff = get_direction_info(range_text, :position_diff, {})
|
151
|
+
position = [x_pos + position_diff[:x].to_i, y_pos + position_diff[:y].to_i]
|
186
152
|
|
187
|
-
|
188
|
-
debug("着弾点:範囲",
|
153
|
+
fire_point[-1] << position
|
154
|
+
debug("着弾点:範囲", fire_point)
|
189
155
|
end
|
190
156
|
end
|
191
157
|
|
192
|
-
debug("\n最終着弾点",
|
158
|
+
debug("\n最終着弾点", fire_point)
|
193
159
|
|
194
|
-
return
|
160
|
+
return fire_point
|
195
161
|
end
|
196
162
|
|
197
|
-
def
|
198
|
-
debug("====
|
163
|
+
def get_fire_point_text(fire_point, _fire_count, direction = 0)
|
164
|
+
debug("====get_fire_point_text====")
|
199
165
|
|
200
|
-
|
201
|
-
|
166
|
+
fire_text_list = []
|
167
|
+
fire_point.each do |point|
|
202
168
|
text = ""
|
203
169
|
point.each do |x, y|
|
204
170
|
# 《弾道学》《回避運動》などによる座標移動
|
205
|
-
x, y =
|
171
|
+
x, y = get_move_point(x, y, direction)
|
206
172
|
|
207
173
|
# マップ外の座標は括弧を付ける
|
208
|
-
text += (
|
174
|
+
text += in_map_position?(x, y) ? "[縦#{y},横#{x}]" : "([縦#{y},横#{x}])"
|
209
175
|
debug("着弾点テキスト", text)
|
210
176
|
end
|
211
177
|
|
212
|
-
|
178
|
+
fire_text_list << text
|
213
179
|
end
|
214
180
|
|
215
|
-
|
216
|
-
|
217
|
-
debug("\n最終着弾点テキスト", fireText)
|
218
|
-
return fireText
|
181
|
+
Result.new(fire_text_list.join(","))
|
219
182
|
end
|
220
183
|
|
221
|
-
def
|
184
|
+
def in_map_position?(x, y)
|
222
185
|
((1 <= y) && (y <= 6)) && ((2 <= x) && (x <= 12))
|
223
186
|
end
|
224
187
|
|
225
|
-
def
|
226
|
-
debug("====
|
188
|
+
def get_move_point(x, y, direction)
|
189
|
+
debug("====get_move_point====")
|
227
190
|
debug("方向", direction)
|
228
|
-
debug("座標移動前x", x)
|
229
|
-
debug("座標移動前y", y)
|
191
|
+
debug("座標移動前(x,y)", x, y)
|
230
192
|
|
231
|
-
position_diff =
|
193
|
+
position_diff = get_direction_info(direction, :position_diff, {})
|
232
194
|
x += position_diff[:x].to_i
|
233
195
|
y += position_diff[:y].to_i
|
234
196
|
|
235
|
-
debug("\n座標移動後x", x)
|
236
|
-
debug("座標移動後y", y)
|
197
|
+
debug("\n座標移動後(x,y)", x, y)
|
237
198
|
return x, y
|
238
199
|
end
|
239
200
|
|
240
|
-
def
|
201
|
+
def get_bomb_result(command)
|
241
202
|
return nil unless (m = %r{^BOM(\d*)?/D([12346789]*)(\[.+\])*/(\d+)(@([2468]))?$}i.match(command))
|
242
203
|
|
243
|
-
debug("====
|
204
|
+
debug("====get_bomb_result====", command)
|
244
205
|
|
245
206
|
target = m[1].to_s
|
246
207
|
direction = m[6].to_i
|
247
208
|
debug("弾道学方向", direction)
|
248
209
|
|
249
|
-
|
250
|
-
text += getJudgeResult("SN" + target) # 砲撃判定
|
210
|
+
sn = get_judge_result("SN" + target) # 砲撃判定
|
251
211
|
|
252
|
-
|
212
|
+
if sn.failure?
|
213
|
+
sn.text = "#{command} > #{sn.text}"
|
214
|
+
return sn
|
215
|
+
end
|
253
216
|
|
254
217
|
# ダメージチェック部分
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
return text
|
218
|
+
fire_command = command.slice(%r{D([12346789]*)(\[.+\])*/(\d+)(@([2468]))?})
|
219
|
+
sn.text = "#{command} > #{sn.text}\n > #{get_fire_result(fire_command).text}"
|
220
|
+
sn
|
260
221
|
end
|
261
222
|
|
262
|
-
def
|
223
|
+
def get_avoid_result(command)
|
263
224
|
return nil unless (m = /^AVO(\d*)?(@([2468]))(\(?\[縦\d+,横\d+\]\)?,?)+$/.match(command))
|
264
225
|
|
265
|
-
debug("====
|
226
|
+
debug("====get_avoid_result====", command)
|
266
227
|
|
267
228
|
direction = m[3].to_i
|
268
229
|
debug("回避方向", direction)
|
269
230
|
|
270
|
-
|
271
|
-
|
272
|
-
text += getJudgeResult("SN" + Regexp.last_match(1).to_s) # 操舵判定
|
231
|
+
judge_command = command.slice(/^AVO(\d*)?(@([2468]))/) # 判定部分
|
232
|
+
sn = get_judge_result("SN" + Regexp.last_match(1).to_s)
|
273
233
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
234
|
+
if sn.failure?
|
235
|
+
sn.text = "#{judge_command} > 《回避運動》#{sn.text}"
|
236
|
+
return sn
|
237
|
+
end
|
238
|
+
point_command = command.slice(/(\(?\[縦\d+,横\d+\]\)?,?)+/) # 砲撃座標
|
239
|
+
|
240
|
+
fire_point = scan_fire_point(point_command)
|
241
|
+
fire_count = fire_point.size
|
242
|
+
Result.success([
|
243
|
+
judge_command,
|
244
|
+
"《回避運動》#{sn.text}\n",
|
245
|
+
point_command,
|
246
|
+
"《回避運動》:" + get_direction_info(direction, :name, "") + "\n",
|
247
|
+
get_fire_point_text(fire_point, fire_count, direction).text
|
248
|
+
].compact.join(" > "))
|
288
249
|
end
|
289
250
|
|
290
|
-
def
|
291
|
-
debug("====
|
251
|
+
def scan_fire_point(command)
|
252
|
+
debug("====scan_fire_point====", command)
|
292
253
|
|
293
254
|
command = command.gsub(/\(|\)/, "") # 正規表現が大変なので最初に括弧を外しておく
|
294
255
|
|
295
|
-
|
256
|
+
fire_point = []
|
296
257
|
|
297
258
|
# 一組ずつに分ける("[縦y,横xの単位)
|
298
|
-
command.split(/\],/).each do |
|
299
|
-
debug("
|
259
|
+
command.split(/\],/).each do |point_text|
|
260
|
+
debug("point_text", point_text)
|
300
261
|
|
301
|
-
|
262
|
+
fire_point << []
|
302
263
|
|
303
264
|
# D以外の砲撃範囲がある時に必要
|
304
|
-
|
265
|
+
point_text.split(/\]/).each do |point|
|
305
266
|
debug("point", point)
|
306
267
|
|
307
|
-
|
268
|
+
fire_point[-1] << []
|
308
269
|
|
309
270
|
next unless point =~ /[^\d]*(\d+),[^\d]*(\d+)/
|
310
271
|
|
311
272
|
y = Regexp.last_match(1).to_i
|
312
273
|
x = Regexp.last_match(2).to_i
|
313
274
|
|
314
|
-
|
275
|
+
fire_point[-1][-1] = [x, y]
|
315
276
|
|
316
|
-
debug("着弾点",
|
277
|
+
debug("着弾点", fire_point)
|
317
278
|
end
|
318
279
|
end
|
319
280
|
|
320
|
-
return
|
281
|
+
return fire_point
|
321
282
|
end
|
322
283
|
end
|
323
284
|
end
|