bcdice 3.1.3 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +186 -76
  3. data/README.md +3 -2
  4. data/i18n/BeginningIdol/ja_jp.yml +2806 -0
  5. data/i18n/BeginningIdol/ko_kr.yml +1400 -0
  6. data/i18n/Cthulhu/zh_hans.yml +11 -0
  7. data/i18n/KillDeathBusiness/ja_jp.yml +1 -1
  8. data/i18n/MagicaLogia/ja_jp.yml +1 -1
  9. data/i18n/MagicaLogia/zh_hans.yml +564 -0
  10. data/i18n/MonotoneMuseum/ko_kr.yml +526 -53
  11. data/i18n/StellarKnights/ja_jp.yml +498 -0
  12. data/i18n/StellarKnights/ko_kr.yml +498 -0
  13. data/i18n/zh_hans.yml +7 -0
  14. data/lib/bcdice/command/parsed.rb +11 -3
  15. data/lib/bcdice/command/parser.rb +179 -100
  16. data/lib/bcdice/common_command/add_dice.rb +1 -1
  17. data/lib/bcdice/common_command/barabara_dice/node.rb +2 -2
  18. data/lib/bcdice/common_command/barabara_dice/result.rb +6 -0
  19. data/lib/bcdice/common_command/calc.rb +1 -1
  20. data/lib/bcdice/common_command/choice.rb +82 -7
  21. data/lib/bcdice/common_command/tally_dice/node.rb +135 -0
  22. data/lib/bcdice/common_command/tally_dice/parser.rb +302 -0
  23. data/lib/bcdice/common_command/tally_dice.rb +19 -0
  24. data/lib/bcdice/common_command.rb +2 -0
  25. data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
  26. data/lib/bcdice/dice_table/d66_left_range_table.rb +29 -0
  27. data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
  28. data/lib/bcdice/dice_table/d66_table.rb +5 -1
  29. data/lib/bcdice/dice_table.rb +3 -0
  30. data/lib/bcdice/game_system/AceKillerGene.rb +1 -1
  31. data/lib/bcdice/game_system/Ainecadette.rb +68 -0
  32. data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
  33. data/lib/bcdice/game_system/Alsetto.rb +1 -1
  34. data/lib/bcdice/game_system/AlterRaise.rb +2 -2
  35. data/lib/bcdice/game_system/Amadeus.rb +110 -93
  36. data/lib/bcdice/game_system/AngelGear.rb +10 -5
  37. data/lib/bcdice/game_system/AnimaAnimus.rb +16 -9
  38. data/lib/bcdice/game_system/Aoharubaan.rb +91 -0
  39. data/lib/bcdice/game_system/Arianrhod.rb +6 -8
  40. data/lib/bcdice/game_system/AssaultEngine.rb +91 -0
  41. data/lib/bcdice/game_system/Avandner.rb +1 -1
  42. data/lib/bcdice/game_system/BadLife.rb +264 -289
  43. data/lib/bcdice/game_system/Bakenokawa.rb +244 -0
  44. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  45. data/lib/bcdice/game_system/BattleTech.rb +109 -28
  46. data/lib/bcdice/game_system/BeastBindTrinity.rb +28 -12
  47. data/lib/bcdice/game_system/BeginningIdol.rb +118 -2392
  48. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +10 -2312
  49. data/lib/bcdice/game_system/BladeOfArcana.rb +1 -1
  50. data/lib/bcdice/game_system/BlindMythos.rb +39 -38
  51. data/lib/bcdice/game_system/BloodCrusade.rb +6 -7
  52. data/lib/bcdice/game_system/BloodMoon.rb +9 -8
  53. data/lib/bcdice/game_system/CardRanker.rb +8 -7
  54. data/lib/bcdice/game_system/CastleInGray.rb +133 -0
  55. data/lib/bcdice/game_system/ChaosFlare.rb +21 -15
  56. data/lib/bcdice/game_system/Chill.rb +10 -10
  57. data/lib/bcdice/game_system/Chill3.rb +9 -9
  58. data/lib/bcdice/game_system/CodeLayerd.rb +39 -39
  59. data/lib/bcdice/game_system/ColossalHunter.rb +34 -47
  60. data/lib/bcdice/game_system/CrashWorld.rb +1 -1
  61. data/lib/bcdice/game_system/Cthulhu.rb +3 -3
  62. data/lib/bcdice/game_system/Cthulhu7th.rb +56 -18
  63. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +1 -1
  64. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +1 -1
  65. data/lib/bcdice/game_system/Cthulhu_SimplifiedChinese.rb +60 -0
  66. data/lib/bcdice/game_system/DarkBlaze.rb +0 -11
  67. data/lib/bcdice/game_system/DarkDaysDrive.rb +8 -7
  68. data/lib/bcdice/game_system/DeadlineHeroes.rb +11 -10
  69. data/lib/bcdice/game_system/DemonParasite.rb +5 -13
  70. data/lib/bcdice/game_system/DesperateRun.rb +1 -1
  71. data/lib/bcdice/game_system/DoubleCross.rb +8 -1
  72. data/lib/bcdice/game_system/Dracurouge.rb +3 -2
  73. data/lib/bcdice/game_system/EclipsePhase.rb +14 -14
  74. data/lib/bcdice/game_system/Elric.rb +18 -14
  75. data/lib/bcdice/game_system/Elysion.rb +1 -1
  76. data/lib/bcdice/game_system/EmbryoMachine.rb +9 -8
  77. data/lib/bcdice/game_system/Emoklore.rb +25 -20
  78. data/lib/bcdice/game_system/FateCoreSystem.rb +117 -0
  79. data/lib/bcdice/game_system/Fiasco.rb +1 -1
  80. data/lib/bcdice/game_system/FilledWith.rb +4 -0
  81. data/lib/bcdice/game_system/FutariSousa.rb +12 -10
  82. data/lib/bcdice/game_system/GURPS.rb +17 -28
  83. data/lib/bcdice/game_system/Garako.rb +1 -1
  84. data/lib/bcdice/game_system/GardenOrder.rb +12 -7
  85. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
  86. data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
  87. data/lib/bcdice/game_system/Gorilla.rb +2 -8
  88. data/lib/bcdice/game_system/GranCrest.rb +189 -417
  89. data/lib/bcdice/game_system/Gundog.rb +9 -8
  90. data/lib/bcdice/game_system/GundogRevised.rb +10 -9
  91. data/lib/bcdice/game_system/GundogZero.rb +1 -1
  92. data/lib/bcdice/game_system/GurpsFW.rb +16 -16
  93. data/lib/bcdice/game_system/HarnMaster.rb +19 -26
  94. data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
  95. data/lib/bcdice/game_system/Hieizan.rb +12 -21
  96. data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
  97. data/lib/bcdice/game_system/HuntersMoon.rb +5 -10
  98. data/lib/bcdice/game_system/InfiniteFantasia.rb +19 -17
  99. data/lib/bcdice/game_system/Insane.rb +13 -20
  100. data/lib/bcdice/game_system/Irisbane.rb +154 -0
  101. data/lib/bcdice/game_system/IthaWenUa.rb +8 -15
  102. data/lib/bcdice/game_system/JamesBond.rb +10 -10
  103. data/lib/bcdice/game_system/JekyllAndHyde.rb +1 -1
  104. data/lib/bcdice/game_system/Kamigakari.rb +1 -1
  105. data/lib/bcdice/game_system/KanColle.rb +4 -9
  106. data/lib/bcdice/game_system/Karukami.rb +84 -0
  107. data/lib/bcdice/game_system/KemonoNoMori.rb +26 -39
  108. data/lib/bcdice/game_system/KillDeathBusiness.rb +7 -15
  109. data/lib/bcdice/game_system/KurayamiCrying.rb +142 -3
  110. data/lib/bcdice/game_system/LiveraDoll.rb +254 -304
  111. data/lib/bcdice/game_system/LogHorizon.rb +10 -7
  112. data/lib/bcdice/game_system/MagicaLogia_SimplifiedChinese.rb +66 -0
  113. data/lib/bcdice/game_system/MeikyuDays.rb +10 -8
  114. data/lib/bcdice/game_system/MeikyuKingdom.rb +26 -26
  115. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +4 -3
  116. data/lib/bcdice/game_system/MetalHead.rb +12 -22
  117. data/lib/bcdice/game_system/MetalHeadExtream.rb +5 -5
  118. data/lib/bcdice/game_system/MonotoneMuseum.rb +8 -6
  119. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
  120. data/lib/bcdice/game_system/Nechronica.rb +63 -90
  121. data/lib/bcdice/game_system/NinjaSlayer.rb +6 -7
  122. data/lib/bcdice/game_system/NjslyrBattle.rb +8 -11
  123. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
  124. data/lib/bcdice/game_system/Paradiso.rb +1 -1
  125. data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
  126. data/lib/bcdice/game_system/Peekaboo.rb +4 -9
  127. data/lib/bcdice/game_system/Pendragon.rb +7 -7
  128. data/lib/bcdice/game_system/PersonaO.rb +86 -0
  129. data/lib/bcdice/game_system/PhantasmAdventure.rb +8 -8
  130. data/lib/bcdice/game_system/Postman.rb +1 -1
  131. data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
  132. data/lib/bcdice/game_system/Raisondetre.rb +2 -2
  133. data/lib/bcdice/game_system/Revulture.rb +123 -0
  134. data/lib/bcdice/game_system/RuneQuest.rb +8 -8
  135. data/lib/bcdice/game_system/Ryutama.rb +1 -1
  136. data/lib/bcdice/game_system/SRS.rb +17 -16
  137. data/lib/bcdice/game_system/SamsaraBallad.rb +38 -11
  138. data/lib/bcdice/game_system/Satasupe.rb +32 -32
  139. data/lib/bcdice/game_system/ScreamHighSchool.rb +5 -5
  140. data/lib/bcdice/game_system/SharedFantasia.rb +19 -23
  141. data/lib/bcdice/game_system/ShinobiGami.rb +14 -6
  142. data/lib/bcdice/game_system/Skynauts.rb +103 -142
  143. data/lib/bcdice/game_system/SkynautsBouken.rb +228 -0
  144. data/lib/bcdice/game_system/StarryDolls.rb +318 -0
  145. data/lib/bcdice/game_system/SteamPunkers.rb +25 -7
  146. data/lib/bcdice/game_system/StellarKnights.rb +85 -706
  147. data/lib/bcdice/game_system/StellarKnights_Korean.rb +79 -0
  148. data/lib/bcdice/game_system/{SterileLife.rb → StellarLife.rb} +162 -226
  149. data/lib/bcdice/game_system/StratoShout.rb +8 -16
  150. data/lib/bcdice/game_system/Strave.rb +1 -1
  151. data/lib/bcdice/game_system/SwordWorld.rb +22 -9
  152. data/lib/bcdice/game_system/SwordWorld2_0.rb +22 -7
  153. data/lib/bcdice/game_system/SwordWorld2_5.rb +8 -2
  154. data/lib/bcdice/game_system/TalesFromTheLoop.rb +83 -0
  155. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  156. data/lib/bcdice/game_system/TokumeiTenkousei.rb +4 -3
  157. data/lib/bcdice/game_system/TokyoGhostResearch.rb +1 -1
  158. data/lib/bcdice/game_system/TorgEternity.rb +2 -2
  159. data/lib/bcdice/game_system/ToshiakiHolyGrailWar.rb +92 -0
  160. data/lib/bcdice/game_system/TrinitySeven.rb +279 -280
  161. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
  162. data/lib/bcdice/game_system/Utakaze.rb +53 -48
  163. data/lib/bcdice/game_system/Villaciel.rb +1 -1
  164. data/lib/bcdice/game_system/WARPS.rb +11 -9
  165. data/lib/bcdice/game_system/WaresBlade.rb +4 -9
  166. data/lib/bcdice/game_system/Warhammer.rb +15 -6
  167. data/lib/bcdice/game_system/Warhammer4.rb +15 -11
  168. data/lib/bcdice/game_system/WitchQuest.rb +1 -1
  169. data/lib/bcdice/game_system/YankeeYogSothoth.rb +4 -9
  170. data/lib/bcdice/game_system/YearZeroEngine.rb +40 -19
  171. data/lib/bcdice/game_system/Yggdrasill.rb +1 -1
  172. data/lib/bcdice/game_system/ZettaiReido.rb +20 -25
  173. data/lib/bcdice/game_system/beginning_idol/accessories_table.rb +31 -0
  174. data/lib/bcdice/game_system/beginning_idol/bad_status_table.rb +43 -0
  175. data/lib/bcdice/game_system/beginning_idol/chain_d66_table.rb +29 -0
  176. data/lib/bcdice/game_system/beginning_idol/chain_table.rb +37 -0
  177. data/lib/bcdice/game_system/beginning_idol/costume_table.rb +37 -0
  178. data/lib/bcdice/game_system/beginning_idol/d6_twice_table.rb +36 -0
  179. data/lib/bcdice/game_system/beginning_idol/item_table.rb +51 -0
  180. data/lib/bcdice/game_system/beginning_idol/my_skill_name_table.rb +44 -0
  181. data/lib/bcdice/game_system/beginning_idol/random_event_table.rb +31 -0
  182. data/lib/bcdice/game_system/beginning_idol/skill_table.rb +63 -0
  183. data/lib/bcdice/game_system/beginning_idol/table.rb +193 -0
  184. data/lib/bcdice/game_system/beginning_idol/with_abnormality.rb +74 -0
  185. data/lib/bcdice/game_system/beginning_idol/work_table.rb +57 -0
  186. data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +1 -1
  187. data/lib/bcdice/game_system/one_way_heroics/random_event_table.rb +4 -4
  188. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +50 -7
  189. data/lib/bcdice/game_system/sword_world/rating_parser.rb +148 -107
  190. data/lib/bcdice/game_system/sword_world/transcendent_test.rb +26 -8
  191. data/lib/bcdice/game_system.rb +18 -1
  192. data/lib/bcdice/repl.rb +1 -1
  193. data/lib/bcdice/result.rb +26 -0
  194. data/lib/bcdice/version.rb +1 -1
  195. metadata +48 -6
@@ -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
- result = getJudgeResult(command)
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
- def getJudgeResult(command)
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("====getJudgeResult====")
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
- diceText = dice_list.join(",")
81
-
62
+ text = "(2D6<=#{target}) > #{total}[#{dice_list.join(',')}] > #{total}"
82
63
  if total <= 2
83
- result = "ファンブル"
64
+ Result.fumble(text + "ファンブル")
84
65
  elsif total <= target
85
- result = "成功"
66
+ Result.success(text + "成功")
86
67
  else
87
- result = "失敗"
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 navigationResult(command)
72
+ def navigation_result(command)
96
73
  return nil unless (m = /^NV(\+(\d+))?$/.match(command))
97
74
 
98
- debug("====navigationResult====")
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
- movePointBase = (total / 2) <= 0 ? 1 : (total / 2)
105
- movePoint = movePointBase + bonus
81
+ move_point_base = (total / 2) <= 0 ? 1 : (total / 2)
82
+ movePoint = move_point_base + bonus
106
83
  debug("移動エリア数", movePoint)
107
84
 
108
- text = "航行チェック(最低1) (1D6/2+#{bonus}) > #{total} /2+#{bonus} > "
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 getDirectionInfo(direction, key, defaultValue = nil)
100
+ def get_direction_info(direction, key, default_value = nil)
127
101
  info = DIRECTION_INFOS[direction.to_i]
128
- return defaultValue if info.nil?
102
+ return default_value if info.nil?
129
103
 
130
104
  return info[key]
131
105
  end
132
106
 
133
- def getFireResult(command)
134
- return nil unless (m = %r{^D([12346789]*)(\[.+\])*/(\d+)(@([2468]))?$}.match(command))
107
+ def get_fire_result(command)
108
+ return nil unless (m = %r{^D([12346789]*)(\[.+\])*/(\d{1,2})(@([2468]))?$}.match(command))
135
109
 
136
- debug("====getFireResult====")
110
+ debug("====get_fire_result====")
137
111
 
138
- fireCount = m[3].to_i # 砲撃回数
139
- fireRange = m[1].to_s # 砲撃範囲
112
+ fire_count = m[3].to_i # 砲撃回数
113
+ fire_range = m[1].to_s # 砲撃範囲
140
114
  ballistics = m[5].to_i # 《弾道学》
141
- debug("fireCount", fireCount)
142
- debug("fireRange", fireRange)
115
+ debug("fire_count", fire_count)
116
+ debug("fire_range", fire_range)
143
117
  debug("ballistics", ballistics)
144
118
 
145
- fireCountMax = 25
146
- fireCount = [fireCount, fireCountMax].min
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
- fireText += " 《弾道学》:"
153
- fireText += getDirectionInfo(ballistics, :name, "")
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 getFirePoint(fireRange, fireCount)
164
- debug("====getFirePoint====")
129
+ def get_fire_point(fire_range, fire_count)
130
+ debug("====get_fire_point====")
165
131
 
166
- firePoint = []
132
+ fire_point = []
167
133
 
168
- fireCount.times do |count|
134
+ fire_count.times do |count|
169
135
  debug("\n砲撃回数", count + 1)
170
136
 
171
- firePoint << []
137
+ fire_point << []
172
138
 
173
- yPos = @randomizer.roll_once(6) # 縦
174
- xPos = @randomizer.roll_sum(2, 6) # 横
175
- position = [xPos, yPos]
139
+ y_pos = @randomizer.roll_once(6) # 縦
140
+ x_pos = @randomizer.roll_sum(2, 6) # 横
141
+ position = [x_pos, y_pos]
176
142
 
177
- firePoint[-1] << position
143
+ fire_point[-1] << position
178
144
 
179
- debug("着弾点", firePoint)
145
+ debug("着弾点", fire_point)
180
146
 
181
- fireRange.split(//).each do |rangeText|
182
- debug("範囲", rangeText)
147
+ fire_range.chars do |range_text|
148
+ debug("範囲", range_text)
183
149
 
184
- position_diff = getDirectionInfo(rangeText, :position_diff, {})
185
- position = [xPos + position_diff[:x].to_i, yPos + position_diff[:y].to_i]
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
- firePoint[-1] << position
188
- debug("着弾点:範囲", firePoint)
153
+ fire_point[-1] << position
154
+ debug("着弾点:範囲", fire_point)
189
155
  end
190
156
  end
191
157
 
192
- debug("\n最終着弾点", firePoint)
158
+ debug("\n最終着弾点", fire_point)
193
159
 
194
- return firePoint
160
+ return fire_point
195
161
  end
196
162
 
197
- def getFirePointText(firePoint, _fireCount, direction = 0)
198
- debug("====getFirePointText====")
163
+ def get_fire_point_text(fire_point, _fire_count, direction = 0)
164
+ debug("====get_fire_point_text====")
199
165
 
200
- fireTextList = []
201
- firePoint.each do |point|
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 = getMovePoint(x, y, direction)
171
+ x, y = get_move_point(x, y, direction)
206
172
 
207
173
  # マップ外の座標は括弧を付ける
208
- text += (isInMapPosition(x, y) ? "[縦#{y},横#{x}]" : "([縦#{y},横#{x}])")
174
+ text += in_map_position?(x, y) ? "[縦#{y},横#{x}]" : "([縦#{y},横#{x}])"
209
175
  debug("着弾点テキスト", text)
210
176
  end
211
177
 
212
- fireTextList << text
178
+ fire_text_list << text
213
179
  end
214
180
 
215
- fireText = fireTextList.join(",")
216
-
217
- debug("\n最終着弾点テキスト", fireText)
218
- return fireText
181
+ Result.new(fire_text_list.join(","))
219
182
  end
220
183
 
221
- def isInMapPosition(x, y)
184
+ def in_map_position?(x, y)
222
185
  ((1 <= y) && (y <= 6)) && ((2 <= x) && (x <= 12))
223
186
  end
224
187
 
225
- def getMovePoint(x, y, direction)
226
- debug("====getMovePoint====")
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 = getDirectionInfo(direction, :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 getBomberResult(command)
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("====getBomberResult====", command)
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
- text = "#{command} > "
250
- text += getJudgeResult("SN" + target) # 砲撃判定
210
+ sn = get_judge_result("SN" + target) # 砲撃判定
251
211
 
252
- return text unless text =~ /成功/
212
+ if sn.failure?
213
+ sn.text = "#{command} > #{sn.text}"
214
+ return sn
215
+ end
253
216
 
254
217
  # ダメージチェック部分
255
- fireCommand = command.slice(%r{D([12346789]*)(\[.+\])*/(\d+)(@([2468]))?})
256
-
257
- text += "\n > #{getFireResult(fireCommand)}"
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 getAvoidResult(command)
223
+ def get_avoid_result(command)
263
224
  return nil unless (m = /^AVO(\d*)?(@([2468]))(\(?\[縦\d+,横\d+\]\)?,?)+$/.match(command))
264
225
 
265
- debug("====getAvoidResult====", command)
226
+ debug("====get_avoid_result====", command)
266
227
 
267
228
  direction = m[3].to_i
268
229
  debug("回避方向", direction)
269
230
 
270
- judgeCommand = command.slice(/^AVO(\d*)?(@([2468]))/) # 判定部分
271
- text = "#{judgeCommand} 《回避運動》"
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
- return text unless text =~ /成功/
275
-
276
- pointCommand = command.slice(/(\(?\[縦\d+,横\d+\]\)?,?)+/) # 砲撃座標
277
-
278
- firePoint = scanFirePoints(pointCommand)
279
- fireCount = firePoint.size
280
-
281
- text += "\n > #{pointCommand}"
282
- text += " > 《回避運動》:"
283
- text += getDirectionInfo(direction, :name, "")
284
- text += "\n"
285
- text += getFirePointText(firePoint, fireCount, direction)
286
-
287
- return text
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 scanFirePoints(command)
291
- debug("====scanFirePoints====", command)
251
+ def scan_fire_point(command)
252
+ debug("====scan_fire_point====", command)
292
253
 
293
254
  command = command.gsub(/\(|\)/, "") # 正規表現が大変なので最初に括弧を外しておく
294
255
 
295
- firePoint = []
256
+ fire_point = []
296
257
 
297
258
  # 一組ずつに分ける("[縦y,横xの単位)
298
- command.split(/\],/).each do |pointText|
299
- debug("pointText", pointText)
259
+ command.split(/\],/).each do |point_text|
260
+ debug("point_text", point_text)
300
261
 
301
- firePoint << []
262
+ fire_point << []
302
263
 
303
264
  # D以外の砲撃範囲がある時に必要
304
- pointText.split(/\]/).each do |point|
265
+ point_text.split(/\]/).each do |point|
305
266
  debug("point", point)
306
267
 
307
- firePoint[-1] << []
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
- firePoint[-1][-1] = [x, y]
275
+ fire_point[-1][-1] = [x, y]
315
276
 
316
- debug("着弾点", firePoint)
277
+ debug("着弾点", fire_point)
317
278
  end
318
279
  end
319
280
 
320
- return firePoint
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