bcdice 3.1.2 → 3.4.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 +154 -75
- data/README.md +3 -2
- data/i18n/Cthulhu/zh_hans.yml +11 -0
- 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/common_command/choice.rb +78 -7
- data/lib/bcdice/dice_table.rb +3 -0
- data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
- data/lib/bcdice/dice_table/d66_left_range_table.rb +29 -0
- data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
- data/lib/bcdice/game_system.rb +10 -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 +10 -5
- 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 +50 -12
- 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/Cthulhu_SimplifiedChinese.rb +60 -0
- 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 +3 -2
- 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 +4 -0
- 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 +189 -417
- 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/Irisbane.rb +154 -0
- 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 +4 -3
- 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/PersonaO.rb +86 -0
- 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 +25 -7
- 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/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/TorgEternity.rb +2 -2
- data/lib/bcdice/game_system/ToshiakiHolyGrailWar.rb +92 -0
- 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/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 +22 -5
|
@@ -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
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BCDice
|
|
4
|
+
module GameSystem
|
|
5
|
+
class SkynautsBouken < Base
|
|
6
|
+
# ゲームシステムの識別子
|
|
7
|
+
ID = 'SkynautsBouken'
|
|
8
|
+
|
|
9
|
+
# ゲームシステム名
|
|
10
|
+
NAME = '歯車の塔の探空士(冒険企画局)'
|
|
11
|
+
|
|
12
|
+
# ゲームシステム名の読みがな
|
|
13
|
+
SORT_KEY = 'はくるまのとうのすかいのおつ2'
|
|
14
|
+
|
|
15
|
+
# ダイスボットの使い方
|
|
16
|
+
HELP_MESSAGE = <<~MESSAGETEXT
|
|
17
|
+
・行為判定(nSNt#f) n:ダイス数(省略時2)、t:目標値(省略時7)、f:ファンブル値(省略時1)
|
|
18
|
+
例)SN6#2 3SN
|
|
19
|
+
・ダメージチェック (Dx/y@m) x:ダメージ範囲、y:攻撃回数
|
|
20
|
+
m:《弾道学》(省略可)上:8、下:2、左:4、右:6
|
|
21
|
+
例) D/4 D19/2 D/3@8 D[大揺れ]/2
|
|
22
|
+
・回避(AVO@mダメージ)
|
|
23
|
+
m:回避方向(上:8、下:2、左:4、右:6)、ダメージ:ダメージチェック結果
|
|
24
|
+
例)AVO@8[1,4],[2,6],[3,8] AVO@2[6,4],[2,6]
|
|
25
|
+
・FT ファンブル表(p76)
|
|
26
|
+
・NV 航行表
|
|
27
|
+
|
|
28
|
+
■ 判定セット
|
|
29
|
+
・《回避運動》判定+回避(nSNt#f/AVO@ダメージ)
|
|
30
|
+
nSNt#f → 成功なら AVO@m
|
|
31
|
+
例)SN/AVO@8[1,4],[2,6],[3,8] 3SN#2/AVO@2[6,4],[2,6]
|
|
32
|
+
・砲撃判定+ダメージチェック (nSNt#f/Dx/y@m)
|
|
33
|
+
行為判定の出目変更タイミングを逃すので要GMの許可
|
|
34
|
+
nSNt#f → 成功なら Dx/y@m
|
|
35
|
+
例)SN/D/4 3SN#2/D[大揺れ]/2
|
|
36
|
+
MESSAGETEXT
|
|
37
|
+
|
|
38
|
+
TABLES = {
|
|
39
|
+
'FT' => DiceTable::Table.new(
|
|
40
|
+
'ファンブル表',
|
|
41
|
+
'1D6', [
|
|
42
|
+
"なんとか大事にはいたらなかった。通常の失敗と同様の処理を行うこと。",
|
|
43
|
+
"転んでしまった。キミは[転倒](p107)する。",
|
|
44
|
+
"失敗にイライラしてしまった。キミは獲得している【キズナ】1つの「支援チェック」にチェックを入れる。",
|
|
45
|
+
"自身のいるマスを[破損](p104)させる。この[破損]によって、キミの【生命点】は減少しない。",
|
|
46
|
+
"頭をぶつけてしまった。キミの【生命点】を「1d6点」減少する。",
|
|
47
|
+
"奇跡的な結果。 この行為判定は成功となる。",
|
|
48
|
+
]
|
|
49
|
+
),
|
|
50
|
+
'NV' => DiceTable::Table.new(
|
|
51
|
+
'航海表',
|
|
52
|
+
'1d6',
|
|
53
|
+
[
|
|
54
|
+
'スポット1つ分進む',
|
|
55
|
+
'スポット1つ分進む',
|
|
56
|
+
'スポット1つ分進む',
|
|
57
|
+
'スポット2つ分進む',
|
|
58
|
+
'スポット2つ分進む',
|
|
59
|
+
'スポット3つ分進む',
|
|
60
|
+
]
|
|
61
|
+
)
|
|
62
|
+
}.freeze
|
|
63
|
+
|
|
64
|
+
register_prefix('D', '\d?SN', 'NV', 'FT', 'AVO')
|
|
65
|
+
|
|
66
|
+
def initialize(command)
|
|
67
|
+
super(command)
|
|
68
|
+
@round_type = RoundType::FLOOR # 端数切り捨て
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def eval_game_system_specific_command(command)
|
|
72
|
+
command_sn(command) || command_d(command) || command_avo(command) || command_snavo(command) ||
|
|
73
|
+
command_snd(command) || roll_tables(command, TABLES)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
DIRECTION_INFOS = {
|
|
79
|
+
0 => {name: "", position_diff: [0, 0]},
|
|
80
|
+
1 => {name: "左下", position_diff: [-1, +1]},
|
|
81
|
+
2 => {name: "下", position_diff: [0, +1]},
|
|
82
|
+
3 => {name: "右下", position_diff: [+1, +1]},
|
|
83
|
+
4 => {name: "左", position_diff: [-1, 0]},
|
|
84
|
+
5 => {name: "", position_diff: [0, 0]},
|
|
85
|
+
6 => {name: "右", position_diff: [+1, 0]},
|
|
86
|
+
7 => {name: "左上", position_diff: [-1, -1]},
|
|
87
|
+
8 => {name: "上", position_diff: [0, -1]},
|
|
88
|
+
9 => {name: "右上", position_diff: [+1, -1]},
|
|
89
|
+
}.freeze
|
|
90
|
+
|
|
91
|
+
D_REGEXP = %r{^D([1-46-9]{0,8})(\[.+\]|S|F|SF|FS)?/(\d{1,2})(@([2468]))?$}.freeze
|
|
92
|
+
|
|
93
|
+
def command_sn(command)
|
|
94
|
+
debug("SN", command)
|
|
95
|
+
cmd = Command::Parser.new(/[1-9]?SN(\d{0,2})/, round_type: round_type)
|
|
96
|
+
.restrict_cmp_op_to(nil)
|
|
97
|
+
.enable_fumble.parse(command)
|
|
98
|
+
return nil unless cmd
|
|
99
|
+
|
|
100
|
+
# [dice_count]SN[target]
|
|
101
|
+
dice_count, target = cmd.command.split("SN", 2).map(&:to_i)
|
|
102
|
+
dice_count = 2 if dice_count == 0
|
|
103
|
+
target = 7 if target == 0
|
|
104
|
+
fumble = cmd.fumble.nil? ? 1 : cmd.fumble
|
|
105
|
+
|
|
106
|
+
debug("SN Parsed", dice_count, target, fumble)
|
|
107
|
+
|
|
108
|
+
dice_list = @randomizer.roll_barabara(dice_count, 6)
|
|
109
|
+
dice_top_two = dice_list.sort[-2..-1]
|
|
110
|
+
res = if dice_top_two == [6, 6]
|
|
111
|
+
Result.critical("スペシャル(【生命点】1d6回復)")
|
|
112
|
+
elsif dice_list.max <= fumble
|
|
113
|
+
Result.fumble("ファンブル(ファンブル表FT)")
|
|
114
|
+
elsif dice_top_two.sum >= target
|
|
115
|
+
Result.success("成功")
|
|
116
|
+
else
|
|
117
|
+
Result.failure("失敗")
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if dice_count == 2
|
|
121
|
+
res.text = ["(#{dice_count}SN#{target}##{fumble})", "#{dice_top_two.sum}[#{dice_list.join(',')}]", res.text]
|
|
122
|
+
.compact.join(" > ")
|
|
123
|
+
else
|
|
124
|
+
res.text = ["(#{dice_count}SN#{target}##{fumble})", "[" + dice_list.join(",") + "]", "#{dice_top_two.sum}[#{dice_top_two.join(',')}]", res.text]
|
|
125
|
+
.compact.join(" > ")
|
|
126
|
+
end
|
|
127
|
+
res
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def command_d(command)
|
|
131
|
+
m = D_REGEXP.match(command)
|
|
132
|
+
return nil unless m
|
|
133
|
+
|
|
134
|
+
fire_count = m[3].to_i # 砲撃回数
|
|
135
|
+
fire_range = m[1].to_s # 砲撃範囲
|
|
136
|
+
ballistics = m[5].to_i # 《弾道学》
|
|
137
|
+
|
|
138
|
+
points = get_fire_points(fire_count, fire_range)
|
|
139
|
+
command = command.sub("SF/", "[大揺れ,火災]/").sub("FS/", "[火災,大揺れ]/").sub("F/", "[火災]/").sub("S/", "[大揺れ]/")
|
|
140
|
+
result = ["(#{command})", get_points_text(points, 0, 0)]
|
|
141
|
+
if ballistics != 0
|
|
142
|
+
dir = DIRECTION_INFOS[ballistics]
|
|
143
|
+
diff_x, diff_y = dir[:position_diff]
|
|
144
|
+
result[-1] += "\n"
|
|
145
|
+
result << "《弾道学》#{dir[:name]}"
|
|
146
|
+
result << get_points_text(points, diff_x, diff_y)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
result.compact.join(" > ")
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def command_avo(command)
|
|
153
|
+
debug("AVO", command)
|
|
154
|
+
dmg = command.match(/^AVO@([2468])(.*?)$/)
|
|
155
|
+
return nil unless dmg
|
|
156
|
+
|
|
157
|
+
dir = DIRECTION_INFOS[dmg[1].to_i]
|
|
158
|
+
diff_x, diff_y = dir[:position_diff]
|
|
159
|
+
"《回避運動》#{dir[:name]} > " + dmg[2].gsub(/\(?\[(\d),(\d{1,2})\]\)?/) do
|
|
160
|
+
y = Regexp.last_match(1).to_i + diff_y
|
|
161
|
+
x = Regexp.last_match(2).to_i + diff_x
|
|
162
|
+
get_xy_text(x, y)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def command_snavo(command)
|
|
167
|
+
sn, avo = command.split(%r{/?AVO}, 2)
|
|
168
|
+
debug("SNAVO", sn, avo)
|
|
169
|
+
am = /^@([2468])(.*?)$/.match(avo)
|
|
170
|
+
return nil unless am
|
|
171
|
+
|
|
172
|
+
res = command_sn(sn)
|
|
173
|
+
return nil unless res
|
|
174
|
+
|
|
175
|
+
if res.success?
|
|
176
|
+
res.text += "\n > " + command_avo("AVO" + avo)
|
|
177
|
+
end
|
|
178
|
+
res
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def command_snd(command)
|
|
182
|
+
sn, d = command.split(%r{/?D}, 2)
|
|
183
|
+
debug("SND", sn, d)
|
|
184
|
+
m = D_REGEXP.match("D#{d}")
|
|
185
|
+
return nil unless m
|
|
186
|
+
|
|
187
|
+
res = command_sn(sn)
|
|
188
|
+
return nil unless res
|
|
189
|
+
|
|
190
|
+
if res.success?
|
|
191
|
+
res.text += "\n > #{command_d('D' + d)}"
|
|
192
|
+
end
|
|
193
|
+
res
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def get_points_text(points, diff_x, diff_y)
|
|
197
|
+
"[縦,横]=" + points.map do |list|
|
|
198
|
+
list.map do |x, y|
|
|
199
|
+
get_xy_text(x + diff_x, y + diff_y)
|
|
200
|
+
end.join()
|
|
201
|
+
end.join(",")
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# 範囲内なら[y,x]、範囲外なら([y,x])と表示
|
|
205
|
+
def get_xy_text(x, y)
|
|
206
|
+
if (2..12).include?(x) && (1..6).include?(y)
|
|
207
|
+
"[#{y},#{x}]"
|
|
208
|
+
else
|
|
209
|
+
"([#{y},#{x}])"
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# 命中場所と範囲から、ダメージ位置を割り出す
|
|
214
|
+
def get_fire_points(fire_count, fire_range)
|
|
215
|
+
range = fire_range.chars.map(&:to_i)
|
|
216
|
+
fire_count.times.map do
|
|
217
|
+
y = @randomizer.roll_once(6) # 縦
|
|
218
|
+
x = @randomizer.roll_sum(2, 6) # 横
|
|
219
|
+
|
|
220
|
+
[[x, y]] + range.map do |r|
|
|
221
|
+
xdiff, ydiff = DIRECTION_INFOS[r][:position_diff]
|
|
222
|
+
[x + xdiff, y + ydiff]
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|