bcdice 3.0.0.pre.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +21 -0
  3. data/.github/.codecov.yaml +10 -0
  4. data/.github/workflows/coverage.yaml +21 -0
  5. data/.github/workflows/lint.yaml +13 -0
  6. data/.github/workflows/test.yml +20 -0
  7. data/.gitignore +14 -0
  8. data/.rubocop.yml +96 -0
  9. data/.rubocop_todo.yml +113 -0
  10. data/CHANGELOG.md +868 -0
  11. data/Gemfile +11 -0
  12. data/LICENSE +29 -0
  13. data/README.md +38 -0
  14. data/ROADMAP.md +30 -0
  15. data/Rakefile +118 -0
  16. data/bcdice.gemspec +27 -0
  17. data/bin/repl.rb +21 -0
  18. data/docs/README.txt +2028 -0
  19. data/docs/dicebot_sort_key.md +72 -0
  20. data/docs/how_to_make_dicebot.md +453 -0
  21. data/lib/bcdice.rb +8 -0
  22. data/lib/bcdice/arithmetic_evaluator.rb +167 -0
  23. data/lib/bcdice/base.rb +423 -0
  24. data/lib/bcdice/command_parser.rb +242 -0
  25. data/lib/bcdice/common_command.rb +23 -0
  26. data/lib/bcdice/common_command/add_dice.rb +54 -0
  27. data/lib/bcdice/common_command/add_dice/node.rb +488 -0
  28. data/lib/bcdice/common_command/add_dice/parser.rb +282 -0
  29. data/lib/bcdice/common_command/add_dice/randomizer.rb +48 -0
  30. data/lib/bcdice/common_command/barabara_dice.rb +57 -0
  31. data/lib/bcdice/common_command/calc.rb +39 -0
  32. data/lib/bcdice/common_command/choice.rb +35 -0
  33. data/lib/bcdice/common_command/d66_dice.rb +63 -0
  34. data/lib/bcdice/common_command/reroll_dice.rb +190 -0
  35. data/lib/bcdice/common_command/upper_dice.rb +165 -0
  36. data/lib/bcdice/common_command/version.rb +26 -0
  37. data/lib/bcdice/dice_table.rb +8 -0
  38. data/lib/bcdice/dice_table/chain_table.rb +33 -0
  39. data/lib/bcdice/dice_table/d66_grid_table.rb +26 -0
  40. data/lib/bcdice/dice_table/d66_range_table.rb +26 -0
  41. data/lib/bcdice/dice_table/d66_table.rb +34 -0
  42. data/lib/bcdice/dice_table/range_table.rb +267 -0
  43. data/lib/bcdice/dice_table/roll_result.rb +43 -0
  44. data/lib/bcdice/dice_table/sai_fic_skill_table.rb +32 -0
  45. data/lib/bcdice/dice_table/table.rb +35 -0
  46. data/lib/bcdice/enum.rb +15 -0
  47. data/lib/bcdice/format.rb +36 -0
  48. data/lib/bcdice/game_system.rb +187 -0
  49. data/lib/bcdice/game_system/AFF2e.rb +141 -0
  50. data/lib/bcdice/game_system/AceKillerGene.rb +55 -0
  51. data/lib/bcdice/game_system/Airgetlamh.rb +117 -0
  52. data/lib/bcdice/game_system/Alsetto.rb +124 -0
  53. data/lib/bcdice/game_system/Alshard.rb +27 -0
  54. data/lib/bcdice/game_system/AlterRaise.rb +282 -0
  55. data/lib/bcdice/game_system/Amadeus.rb +622 -0
  56. data/lib/bcdice/game_system/Amadeus_Korean.rb +501 -0
  57. data/lib/bcdice/game_system/AnimaAnimus.rb +96 -0
  58. data/lib/bcdice/game_system/Arianrhod.rb +50 -0
  59. data/lib/bcdice/game_system/ArsMagica.rb +149 -0
  60. data/lib/bcdice/game_system/Avandner.rb +101 -0
  61. data/lib/bcdice/game_system/BBN.rb +143 -0
  62. data/lib/bcdice/game_system/BadLife.rb +435 -0
  63. data/lib/bcdice/game_system/BarnaKronika.rb +188 -0
  64. data/lib/bcdice/game_system/BattleTech.rb +530 -0
  65. data/lib/bcdice/game_system/BeastBindTrinity.rb +348 -0
  66. data/lib/bcdice/game_system/BeginningIdol.rb +2527 -0
  67. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +2378 -0
  68. data/lib/bcdice/game_system/BladeOfArcana.rb +252 -0
  69. data/lib/bcdice/game_system/BlindMythos.rb +460 -0
  70. data/lib/bcdice/game_system/BloodCrusade.rb +423 -0
  71. data/lib/bcdice/game_system/BloodMoon.rb +213 -0
  72. data/lib/bcdice/game_system/CardRanker.rb +249 -0
  73. data/lib/bcdice/game_system/ChaosFlare.rb +181 -0
  74. data/lib/bcdice/game_system/Chill.rb +163 -0
  75. data/lib/bcdice/game_system/Chill3.rb +52 -0
  76. data/lib/bcdice/game_system/CodeLayerd.rb +132 -0
  77. data/lib/bcdice/game_system/ColossalHunter.rb +569 -0
  78. data/lib/bcdice/game_system/CrashWorld.rb +81 -0
  79. data/lib/bcdice/game_system/Cthulhu.rb +252 -0
  80. data/lib/bcdice/game_system/Cthulhu7th.rb +767 -0
  81. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +386 -0
  82. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +383 -0
  83. data/lib/bcdice/game_system/CthulhuTech.rb +263 -0
  84. data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +243 -0
  85. data/lib/bcdice/game_system/Cthulhu_Korean.rb +240 -0
  86. data/lib/bcdice/game_system/DarkBlaze.rb +207 -0
  87. data/lib/bcdice/game_system/DarkDaysDrive.rb +425 -0
  88. data/lib/bcdice/game_system/DarkSouls.rb +91 -0
  89. data/lib/bcdice/game_system/DeadlineHeroes.rb +583 -0
  90. data/lib/bcdice/game_system/DemonParasite.rb +524 -0
  91. data/lib/bcdice/game_system/DetatokoSaga.rb +310 -0
  92. data/lib/bcdice/game_system/DetatokoSaga_Korean.rb +310 -0
  93. data/lib/bcdice/game_system/DiceBot.rb +17 -0
  94. data/lib/bcdice/game_system/DiceOfTheDead.rb +111 -0
  95. data/lib/bcdice/game_system/DoubleCross.rb +373 -0
  96. data/lib/bcdice/game_system/DoubleCross_Korean.rb +371 -0
  97. data/lib/bcdice/game_system/Dracurouge.rb +1856 -0
  98. data/lib/bcdice/game_system/Dracurouge_Korean.rb +310 -0
  99. data/lib/bcdice/game_system/DungeonsAndDragons.rb +19 -0
  100. data/lib/bcdice/game_system/EarthDawn.rb +225 -0
  101. data/lib/bcdice/game_system/EarthDawn3.rb +275 -0
  102. data/lib/bcdice/game_system/EarthDawn4.rb +272 -0
  103. data/lib/bcdice/game_system/EclipsePhase.rb +51 -0
  104. data/lib/bcdice/game_system/Elric.rb +36 -0
  105. data/lib/bcdice/game_system/Elysion.rb +1213 -0
  106. data/lib/bcdice/game_system/EmbryoMachine.rb +227 -0
  107. data/lib/bcdice/game_system/EndBreaker.rb +132 -0
  108. data/lib/bcdice/game_system/EtrianOdysseySRS.rb +27 -0
  109. data/lib/bcdice/game_system/Fiasco.rb +123 -0
  110. data/lib/bcdice/game_system/Fiasco_Korean.rb +122 -0
  111. data/lib/bcdice/game_system/FilledWith.rb +1543 -0
  112. data/lib/bcdice/game_system/FullMetalPanic.rb +27 -0
  113. data/lib/bcdice/game_system/FutariSousa.rb +994 -0
  114. data/lib/bcdice/game_system/FutariSousa_Korean.rb +994 -0
  115. data/lib/bcdice/game_system/Garako.rb +559 -0
  116. data/lib/bcdice/game_system/GardenOrder.rb +451 -0
  117. data/lib/bcdice/game_system/GehennaAn.rb +136 -0
  118. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +120 -0
  119. data/lib/bcdice/game_system/GoblinSlayer.rb +168 -0
  120. data/lib/bcdice/game_system/GoldenSkyStories.rb +77 -0
  121. data/lib/bcdice/game_system/Gorilla.rb +44 -0
  122. data/lib/bcdice/game_system/GranCrest.rb +518 -0
  123. data/lib/bcdice/game_system/Gundog.rb +52 -0
  124. data/lib/bcdice/game_system/GundogRevised.rb +294 -0
  125. data/lib/bcdice/game_system/GundogZero.rb +261 -0
  126. data/lib/bcdice/game_system/Gurps.rb +403 -0
  127. data/lib/bcdice/game_system/GurpsFW.rb +2330 -0
  128. data/lib/bcdice/game_system/HarnMaster.rb +208 -0
  129. data/lib/bcdice/game_system/HatsuneMiku.rb +706 -0
  130. data/lib/bcdice/game_system/Hieizan.rb +48 -0
  131. data/lib/bcdice/game_system/HouraiGakuen.rb +270 -0
  132. data/lib/bcdice/game_system/HuntersMoon.rb +503 -0
  133. data/lib/bcdice/game_system/Illusio.rb +89 -0
  134. data/lib/bcdice/game_system/InfiniteFantasia.rb +51 -0
  135. data/lib/bcdice/game_system/Insane.rb +822 -0
  136. data/lib/bcdice/game_system/Insane_Korean.rb +773 -0
  137. data/lib/bcdice/game_system/IthaWenUa.rb +38 -0
  138. data/lib/bcdice/game_system/JamesBond.rb +45 -0
  139. data/lib/bcdice/game_system/Kamigakari.rb +394 -0
  140. data/lib/bcdice/game_system/Kamigakari_Korean.rb +428 -0
  141. data/lib/bcdice/game_system/KanColle.rb +938 -0
  142. data/lib/bcdice/game_system/KemonoNoMori.rb +258 -0
  143. data/lib/bcdice/game_system/KillDeathBusiness.rb +1420 -0
  144. data/lib/bcdice/game_system/KillDeathBusiness_Korean.rb +1510 -0
  145. data/lib/bcdice/game_system/KurayamiCrying.rb +49 -0
  146. data/lib/bcdice/game_system/LiveraDoll.rb +375 -0
  147. data/lib/bcdice/game_system/LogHorizon.rb +3567 -0
  148. data/lib/bcdice/game_system/LogHorizon_Korean.rb +1407 -0
  149. data/lib/bcdice/game_system/LostRecord.rb +30 -0
  150. data/lib/bcdice/game_system/LostRoyal.rb +242 -0
  151. data/lib/bcdice/game_system/MagicaLogia.rb +1148 -0
  152. data/lib/bcdice/game_system/MeikyuDays.rb +415 -0
  153. data/lib/bcdice/game_system/MeikyuKingdom.rb +466 -0
  154. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +269 -0
  155. data/lib/bcdice/game_system/MetalHead.rb +249 -0
  156. data/lib/bcdice/game_system/MetalHeadExtream.rb +917 -0
  157. data/lib/bcdice/game_system/MetallicGuardian.rb +31 -0
  158. data/lib/bcdice/game_system/MonotoneMuseum.rb +354 -0
  159. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +304 -0
  160. data/lib/bcdice/game_system/Nechronica.rb +211 -0
  161. data/lib/bcdice/game_system/Nechronica_Korean.rb +160 -0
  162. data/lib/bcdice/game_system/NeverCloud.rb +74 -0
  163. data/lib/bcdice/game_system/NightWizard.rb +231 -0
  164. data/lib/bcdice/game_system/NightWizard3rd.rb +24 -0
  165. data/lib/bcdice/game_system/NightmareHunterDeep.rb +117 -0
  166. data/lib/bcdice/game_system/NinjaSlayer.rb +274 -0
  167. data/lib/bcdice/game_system/NjslyrBattle.rb +54 -0
  168. data/lib/bcdice/game_system/Nuekagami.rb +293 -0
  169. data/lib/bcdice/game_system/OneWayHeroics.rb +134 -0
  170. data/lib/bcdice/game_system/OracleEngine.rb +265 -0
  171. data/lib/bcdice/game_system/OrgaRain.rb +77 -0
  172. data/lib/bcdice/game_system/Oukahoushin3rd.rb +162 -0
  173. data/lib/bcdice/game_system/Paradiso.rb +323 -0
  174. data/lib/bcdice/game_system/Paranoia.rb +64 -0
  175. data/lib/bcdice/game_system/ParanoiaRebooted.rb +109 -0
  176. data/lib/bcdice/game_system/ParasiteBlood.rb +231 -0
  177. data/lib/bcdice/game_system/Pathfinder.rb +21 -0
  178. data/lib/bcdice/game_system/Peekaboo.rb +324 -0
  179. data/lib/bcdice/game_system/Pendragon.rb +39 -0
  180. data/lib/bcdice/game_system/PhantasmAdventure.rb +73 -0
  181. data/lib/bcdice/game_system/Postman.rb +185 -0
  182. data/lib/bcdice/game_system/PulpCthulhu.rb +184 -0
  183. data/lib/bcdice/game_system/Raisondetre.rb +171 -0
  184. data/lib/bcdice/game_system/RecordOfLodossWar.rb +58 -0
  185. data/lib/bcdice/game_system/RecordOfSteam.rb +149 -0
  186. data/lib/bcdice/game_system/RokumonSekai2.rb +110 -0
  187. data/lib/bcdice/game_system/RoleMaster.rb +24 -0
  188. data/lib/bcdice/game_system/RuneQuest.rb +47 -0
  189. data/lib/bcdice/game_system/RyuTuber.rb +266 -0
  190. data/lib/bcdice/game_system/Ryutama.rb +199 -0
  191. data/lib/bcdice/game_system/SRS.rb +348 -0
  192. data/lib/bcdice/game_system/SamsaraBallad.rb +111 -0
  193. data/lib/bcdice/game_system/Satasupe.rb +1173 -0
  194. data/lib/bcdice/game_system/ScreamHighSchool.rb +128 -0
  195. data/lib/bcdice/game_system/SevenFortressMobius.rb +34 -0
  196. data/lib/bcdice/game_system/ShadowRun.rb +26 -0
  197. data/lib/bcdice/game_system/ShadowRun4.rb +49 -0
  198. data/lib/bcdice/game_system/ShadowRun5.rb +80 -0
  199. data/lib/bcdice/game_system/SharedFantasia.rb +69 -0
  200. data/lib/bcdice/game_system/ShinMegamiTenseiKakuseihen.rb +85 -0
  201. data/lib/bcdice/game_system/ShinkuuGakuen.rb +506 -0
  202. data/lib/bcdice/game_system/ShinobiGami.rb +680 -0
  203. data/lib/bcdice/game_system/ShoujoTenrankai.rb +677 -0
  204. data/lib/bcdice/game_system/Skynauts.rb +324 -0
  205. data/lib/bcdice/game_system/SteamPunkers.rb +485 -0
  206. data/lib/bcdice/game_system/StellarKnights.rb +856 -0
  207. data/lib/bcdice/game_system/SterileLife.rb +452 -0
  208. data/lib/bcdice/game_system/StrangerOfSwordCity.rb +103 -0
  209. data/lib/bcdice/game_system/StratoShout.rb +316 -0
  210. data/lib/bcdice/game_system/StratoShout_Korean.rb +314 -0
  211. data/lib/bcdice/game_system/Strave.rb +223 -0
  212. data/lib/bcdice/game_system/SwordWorld.rb +491 -0
  213. data/lib/bcdice/game_system/SwordWorld2_0.rb +295 -0
  214. data/lib/bcdice/game_system/SwordWorld2_5.rb +121 -0
  215. data/lib/bcdice/game_system/TherapieSein.rb +93 -0
  216. data/lib/bcdice/game_system/TokumeiTenkousei.rb +96 -0
  217. data/lib/bcdice/game_system/TokyoGhostResearch.rb +122 -0
  218. data/lib/bcdice/game_system/TokyoNova.rb +19 -0
  219. data/lib/bcdice/game_system/Torg.rb +364 -0
  220. data/lib/bcdice/game_system/Torg1_5.rb +139 -0
  221. data/lib/bcdice/game_system/TorgEternity.rb +414 -0
  222. data/lib/bcdice/game_system/TrinitySeven.rb +364 -0
  223. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +287 -0
  224. data/lib/bcdice/game_system/TwilightGunsmoke.rb +527 -0
  225. data/lib/bcdice/game_system/Utakaze.rb +153 -0
  226. data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +132 -0
  227. data/lib/bcdice/game_system/Villaciel.rb +555 -0
  228. data/lib/bcdice/game_system/WARPS.rb +33 -0
  229. data/lib/bcdice/game_system/WaresBlade.rb +34 -0
  230. data/lib/bcdice/game_system/Warhammer.rb +336 -0
  231. data/lib/bcdice/game_system/WitchQuest.rb +275 -0
  232. data/lib/bcdice/game_system/WorldOfDarkness.rb +135 -0
  233. data/lib/bcdice/game_system/YankeeYogSothoth.rb +440 -0
  234. data/lib/bcdice/game_system/YearZeroEngine.rb +134 -0
  235. data/lib/bcdice/game_system/ZettaiReido.rb +142 -0
  236. data/lib/bcdice/game_system/meikyu_kingdom/item_table.rb +383 -0
  237. data/lib/bcdice/game_system/meikyu_kingdom/kingdom_name_table.rb +89 -0
  238. data/lib/bcdice/game_system/meikyu_kingdom/landscape_table.rb +196 -0
  239. data/lib/bcdice/game_system/meikyu_kingdom/name_tables.rb +223 -0
  240. data/lib/bcdice/game_system/meikyu_kingdom/placename_table.rb +214 -0
  241. data/lib/bcdice/game_system/meikyu_kingdom/tables.rb +610 -0
  242. data/lib/bcdice/game_system/meikyu_kingdom/word_table.rb +117 -0
  243. data/lib/bcdice/game_system/meikyu_kingdom_basic/item_table.rb +380 -0
  244. data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +184 -0
  245. data/lib/bcdice/game_system/meikyu_kingdom_basic/name_table.rb +417 -0
  246. data/lib/bcdice/game_system/meikyu_kingdom_basic/table.rb +912 -0
  247. data/lib/bcdice/game_system/meikyu_kingdom_basic/word_table.rb +121 -0
  248. data/lib/bcdice/game_system/one_way_heroics/dungeon_table.rb +67 -0
  249. data/lib/bcdice/game_system/one_way_heroics/random_event_table.rb +166 -0
  250. data/lib/bcdice/game_system/one_way_heroics/tables.rb +668 -0
  251. data/lib/bcdice/loader.rb +37 -0
  252. data/lib/bcdice/normalize.rb +38 -0
  253. data/lib/bcdice/preprocessor.rb +87 -0
  254. data/lib/bcdice/randomizer.rb +137 -0
  255. data/lib/bcdice/repl.rb +155 -0
  256. data/lib/bcdice/user_defined_dice_table.rb +153 -0
  257. data/lib/bcdice/version.rb +3 -0
  258. metadata +304 -0
@@ -0,0 +1,17 @@
1
+ module BCDice
2
+ module GameSystem
3
+ class DiceBot < Base
4
+ # ゲームシステムの識別子
5
+ ID = 'DiceBot'.freeze
6
+
7
+ # ゲームシステム名
8
+ NAME = 'DiceBot'.freeze
9
+
10
+ # ゲームシステム名の読みがな
11
+ SORT_KEY = '*たいすほつと'.freeze
12
+
13
+ # ダイスボットの使い方
14
+ HELP_MESSAGE = ''.freeze
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class DiceOfTheDead < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'DiceOfTheDead'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'ダイス・オブ・ザ・デッド'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'たいすおふさてつと'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
+ ・ゾンビ化表 ZMB+x
18
+ (x=オープン中の感染度マスの数。+xは省略可能、省略時は0)
19
+ ・感染度表 BIOx
20
+ (xは被弾回数。xは省略可能、省略時は1)
21
+ (上記二つは最初からシークレットダイスで行われます)
22
+ INFO_MESSAGE_TEXT
23
+
24
+ register_prefix(['(ZMB|BIO).*'])
25
+
26
+ def initialize(command)
27
+ super(command)
28
+
29
+ @sort_add_dice = true
30
+ @enabled_d66 = true
31
+ @d66_sort_type = D66SortType::ASC
32
+ end
33
+
34
+ def eval_game_system_specific_command(command)
35
+ case command
36
+ when /^BIO(\d+)?$/
37
+ roll_times = (Regexp.last_match(1) || 1).to_i
38
+ @is_secret = true
39
+
40
+ return checkInfection(roll_times)
41
+ when /^ZMB(\+(\d+))?$/
42
+ value = Regexp.last_match(2).to_i
43
+ @is_secret = true
44
+
45
+ return rollZombie(value)
46
+ end
47
+ end
48
+
49
+ def checkInfection(roll_times)
50
+ result = "感染度表"
51
+
52
+ roll_times.times do
53
+ d1 = @randomizer.roll_once(6)
54
+ d2 = @randomizer.roll_once(6)
55
+
56
+ result += " > 出目:#{d1}、#{d2} "
57
+
58
+ index1 = (d1 / 2.0).ceil - 1
59
+ index2 = (d2 / 2.0).ceil - 1
60
+
61
+ table =
62
+ [["「右下(【足】+1)」", "「右中(【足】+1)」", "「右上(【足】+1)」"],
63
+ ["「中下(【腕】+1)」", "「真中(【腕】+1)」", "「中上(【腕】+1)」"],
64
+ ["「左下(【頭】+1)」", "「左中(【頭】+1)」", "「左上(【頭】+1)」"],]
65
+
66
+ result += table[index1][index2]
67
+ end
68
+
69
+ return result
70
+ end
71
+
72
+ ####################
73
+ # 各種表
74
+
75
+ def rollZombie(value)
76
+ d1 = @randomizer.roll_once(6)
77
+ d2 = @randomizer.roll_once(6)
78
+
79
+ diceTotal = d1 + d2 + value
80
+
81
+ table = [
82
+ [5, "5以下:影響なし"],
83
+ [6, "6:任意の部位を1点回復"],
84
+ [7, "7:〈アイテム〉武器を1つその場に落とす"],
85
+ [8, "8:〈アイテム〉便利道具1つをその場に落とす"],
86
+ [9, "9:〈アイテム〉消耗品1つをその場に落とす"],
87
+ [10, "10:腕の傷が広がる。「部位:【腕】」1点ダメージ"],
88
+ [11, "11:足の傷が広がる。「部位:【足】」1点ダメージ"],
89
+ [12, "12:頭の傷が広がる。「部位:【頭】」1点ダメージ"],
90
+ [13, "13:【ゾンビ化表】が新たに適用されるまで「【感染度】+1マス」の効果を受ける"],
91
+ [14, "14:即座に自分以外の味方1人のスロット内の〈アイテム〉1つをランダムに捨てさせる"],
92
+ [15, "15:味方1人に素手で攻撃を行う"],
93
+ [16, "16:即座に感染度が1上昇する"],
94
+ [17, "17:次のターンのみ、すべての【能力値】を2倍にする"],
95
+ [18, "18以上:自分以外の味方1人にできる限り全力で攻撃を行う。〈アイテム〉も可能な限り使用する"]
96
+ ]
97
+
98
+ minDice = table.first.first
99
+ maxDice = table.last.first
100
+ index = diceTotal
101
+ index = [minDice, index].max
102
+ index = [index, maxDice].min
103
+
104
+ _number, text = table.assoc(index)
105
+ result = "ゾンビ化表 > 出目:#{d1}+#{d2} 感染度:#{value} 合計値:#{diceTotal} > #{text}"
106
+
107
+ return result
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdice/arithmetic_evaluator'
4
+ require 'bcdice/dice_table/range_table'
5
+
6
+ module BCDice
7
+ module GameSystem
8
+ class DoubleCross < Base
9
+ # ゲームシステムの識別子
10
+ ID = 'DoubleCross'
11
+
12
+ # ゲームシステム名
13
+ NAME = 'ダブルクロス2nd,3rd'
14
+
15
+ # ゲームシステム名の読みがな
16
+ SORT_KEY = 'たふるくろす2'
17
+
18
+ # ダイスボットの使い方
19
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
20
+ ・判定コマンド(xDX+y@c or xDXc+y)
21
+  "(個数)DX(修正)@(クリティカル値)" もしくは "(個数)DX(クリティカル値)(修正)" で指定します。
22
+  修正値も付けられます。
23
+  例)10dx  10dx+5@8(OD tool式)  5DX7+7-3(疾風怒濤式)
24
+
25
+ ・各種表
26
+  ・感情表(ET)
27
+   ポジティブとネガティブの両方を振って、表になっている側に○を付けて表示します。
28
+   もちろん任意で選ぶ部分は変更して構いません。
29
+
30
+ ・D66ダイスあり
31
+ INFO_MESSAGE_TEXT
32
+
33
+ register_prefix(['\d+DX.*', 'ET'])
34
+
35
+ # 成功判定コマンドのノード
36
+ class DX
37
+ # ノードを初期化する
38
+ # @param [Integer] num ダイス数
39
+ # @param [Integer] critical_value クリティカル値
40
+ # @param [Integer] modifier 修正値
41
+ # @param [Integer] target_value 目標値
42
+ def initialize(num, critical_value, modifier, target_value)
43
+ @num = num
44
+ @critical_value = critical_value
45
+ @modifier = modifier
46
+ @target_value = target_value
47
+
48
+ @modifier_str = Format.modifier(@modifier)
49
+ @expression = node_expression()
50
+ end
51
+
52
+ # 成功判定を行う
53
+ # @param randomizer [Randomizer]
54
+ # @return [String] 判定結果
55
+ def execute(randomizer)
56
+ if @critical_value < 2
57
+ return "(#{@expression}) > クリティカル値が低すぎます。2以上を指定してください。"
58
+ end
59
+
60
+ if @num < 1
61
+ return "(#{@expression}) > 自動失敗"
62
+ end
63
+
64
+ # 出目のグループの配列
65
+ value_groups = []
66
+ # 次にダイスロールを行う際のダイス数
67
+ num_of_dice = @num
68
+ # 回転数
69
+ loop_count = 0
70
+
71
+ while num_of_dice > 0 && loop_count < CommonCommand::RerollDice::REROLL_LIMIT
72
+ values = randomizer.roll_barabara(num_of_dice, 10)
73
+
74
+ value_group = ValueGroup.new(values, @critical_value)
75
+ value_groups.push(value_group)
76
+
77
+ # 次回はクリティカル発生数と等しい個数のダイスを振る
78
+ # [3rd ルールブック1 p. 185]
79
+ num_of_dice = value_group.num_of_critical_occurrences
80
+
81
+ loop_count += 1
82
+ end
83
+
84
+ return result_str(value_groups)
85
+ end
86
+
87
+ private
88
+
89
+ # 数式表記を返す
90
+ # @return [String]
91
+ def node_expression
92
+ lhs = "#{@num}DX#{@critical_value}#{@modifier_str}"
93
+
94
+ return @target_value ? "#{lhs}>=#{@target_value}" : lhs
95
+ end
96
+
97
+ # 判定結果の文字列を返す
98
+ # @param [Array<ValueGroup>] value_groups 出目のグループの配列
99
+ # @return [String]
100
+ def result_str(value_groups)
101
+ fumble = value_groups[0].values.all? { |value| value == 1 }
102
+ # TODO: Ruby 2.4以降では Array#sum が使える
103
+ sum = value_groups.map(&:max).reduce(0, &:+)
104
+ achieved_value = fumble ? 0 : (sum + @modifier)
105
+
106
+ parts = [
107
+ "(#{@expression})",
108
+ "#{value_groups.join('+')}#{@modifier_str}",
109
+ achieved_value_with_if_fumble(achieved_value, fumble),
110
+ compare_result(achieved_value, fumble)
111
+ ]
112
+
113
+ return parts.compact.join(' > ')
114
+ end
115
+
116
+ # ファンブルかどうかを含む達成値の表記を返す
117
+ # @param [Integer] achieved_value 達成値
118
+ # @param [Boolean] fumble ファンブルしたか
119
+ # @return [String]
120
+ def achieved_value_with_if_fumble(achieved_value, fumble)
121
+ fumble ? "#{achieved_value} (ファンブル)" : achieved_value.to_s
122
+ end
123
+
124
+ # 達成値と目標値を比較した結果を返す
125
+ # @param [Integer] achieved_value 達成値
126
+ # @param [Boolean] fumble ファンブルしたか
127
+ # @return [String, nil]
128
+ def compare_result(achieved_value, fumble)
129
+ return nil unless @target_value
130
+
131
+ # ファンブル時は自動失敗
132
+ # [3rd ルールブック1 pp. 186-187]
133
+ return '失敗' if fumble
134
+
135
+ # 達成値が目標値以上ならば行為判定成功
136
+ # [3rd ルールブック1 p. 187]
137
+ return achieved_value >= @target_value ? '成功' : '失敗'
138
+ end
139
+ end
140
+
141
+ # 出目のグループを表すクラス
142
+ class ValueGroup
143
+ # 出目の配列
144
+ # @return [Array<Integer>]
145
+ attr_reader :values
146
+ # クリティカル値
147
+ # @return [Integer]
148
+ attr_reader :critical_value
149
+
150
+ # 出目のグループを初期化する
151
+ # @param [Array<Integer>] values 出目の配列
152
+ # @param [Integer] critical_value クリティカル値
153
+ def initialize(values, critical_value)
154
+ @values = values.sort
155
+ @critical_value = critical_value
156
+ end
157
+
158
+ # 出目のグループの文字列表記を返す
159
+ # @return [String]
160
+ def to_s
161
+ "#{max}[#{@values.join(',')}]"
162
+ end
163
+
164
+ # 出目のグループ中の最大値を返す
165
+ # @return [Integer]
166
+ #
167
+ # クリティカル値以上の出目が含まれていた場合は10を返す。
168
+ # [3rd ルールブック1 pp. 185-186]
169
+ def max
170
+ @values.any? { |value| critical?(value) } ? 10 : @values.max
171
+ end
172
+
173
+ # クリティカルの発生数を返す
174
+ # @return [Integer]
175
+ def num_of_critical_occurrences
176
+ @values
177
+ .select { |value| critical?(value) }
178
+ .length
179
+ end
180
+
181
+ private
182
+
183
+ # クリティカルが発生したかを返す
184
+ # @param [Integer] value 出目
185
+ # @return [Boolean]
186
+ #
187
+ # クリティカル値以上の値が出た場合、クリティカルとする。
188
+ # [3rd ルールブック1 pp. 185-186]
189
+ def critical?(value)
190
+ value >= @critical_value
191
+ end
192
+ end
193
+
194
+ def check_nD10(total, _dice_total, dice_list, cmp_op, target)
195
+ return '' if target == '?'
196
+ return '' unless cmp_op == :>=
197
+
198
+ if dice_list.count(1) == dice_list.size
199
+ " > ファンブル"
200
+ elsif total >= target
201
+ " > 成功"
202
+ else
203
+ " > 失敗"
204
+ end
205
+ end
206
+
207
+ # ダイスボット固有コマンドの処理を行う
208
+ # @param [String] command コマンド
209
+ # @return [String] ダイスボット固有コマンドの結果
210
+ # @return [nil] 無効なコマンドだった場合
211
+ def eval_game_system_specific_command(command)
212
+ if (dx = parse_dx(command))
213
+ return dx.execute(@randomizer)
214
+ end
215
+
216
+ if command == 'ET'
217
+ return roll_emotion_table()
218
+ end
219
+
220
+ return nil
221
+ end
222
+
223
+ private
224
+
225
+ # OD Tool式の成功判定コマンドの正規表現
226
+ #
227
+ # キャプチャ内容は以下のとおり:
228
+ #
229
+ # 1. ダイス数
230
+ # 2. 修正値
231
+ # 3. クリティカル値
232
+ # 4. 達成値
233
+ DX_OD_TOOL_RE = /\A(\d+)DX([-+]\d+(?:[-+*]\d+)*)?@(\d+)(?:>=(\d+))?\z/io.freeze
234
+
235
+ # 疾風怒濤式の成功判定コマンドの正規表現
236
+ #
237
+ # キャプチャ内容は以下のとおり:
238
+ #
239
+ # 1. ダイス数
240
+ # 2. クリティカル値
241
+ # 3. 修正値
242
+ # 4. 達成値
243
+ DX_SHIPPU_DOTO_RE = /\A(\d+)DX(\d+)?([-+]\d+(?:[-+*]\d+)*)?(?:>=(\d+))?\z/io.freeze
244
+
245
+ # 成功判定コマンドの構文解析を行う
246
+ # @param [String] command コマンド文字列
247
+ # @return [DX, nil]
248
+ def parse_dx(command)
249
+ case command
250
+ when DX_OD_TOOL_RE
251
+ return parse_dx_od(Regexp.last_match)
252
+ when DX_SHIPPU_DOTO_RE
253
+ return parse_dx_shippu_doto(Regexp.last_match)
254
+ end
255
+
256
+ return nil
257
+ end
258
+
259
+ # OD Tool式の成功判定コマンドの正規表現マッチ情報からノードを作る
260
+ # @param [MatchData] m 正規表現のマッチ情報
261
+ # @return [DX]
262
+ def parse_dx_od(m)
263
+ num = m[1].to_i
264
+ modifier = m[2] ? ArithmeticEvaluator.eval(m[2]) : 0
265
+ critical_value = m[3] ? m[3].to_i : 10
266
+
267
+ target_value = m[4]&.to_i
268
+
269
+ return DX.new(num, critical_value, modifier, target_value)
270
+ end
271
+
272
+ # 疾風怒濤式の成功判定コマンドの正規表現マッチ情報からノードを作る
273
+ # @param [MatchData] m 正規表現のマッチ情報
274
+ # @return [DX]
275
+ def parse_dx_shippu_doto(m)
276
+ num = m[1].to_i
277
+ critical_value = m[2] ? m[2].to_i : 10
278
+ modifier = m[3] ? ArithmeticEvaluator.eval(m[3]) : 0
279
+
280
+ target_value = m[4]&.to_i
281
+
282
+ return DX.new(num, critical_value, modifier, target_value)
283
+ end
284
+
285
+ # 感情表を振る
286
+ #
287
+ # ポジティブとネガティブの両方を振って、表になっている側に○を付ける。
288
+ #
289
+ # @return [String]
290
+ def roll_emotion_table
291
+ pos_result = POSITIVE_EMOTION_TABLE.roll(@randomizer)
292
+ neg_result = NEGATIVE_EMOTION_TABLE.roll(@randomizer)
293
+
294
+ positive = @randomizer.roll_once(2) == 1
295
+ pos_neg_text =
296
+ if positive
297
+ ["○#{pos_result.content}", neg_result.content]
298
+ else
299
+ [pos_result.content, "○#{neg_result.content}"]
300
+ end
301
+
302
+ output_parts = [
303
+ "感情表(#{pos_result.sum}-#{neg_result.sum})",
304
+ pos_neg_text.join(' - ')
305
+ ]
306
+
307
+ return output_parts.join(' > ')
308
+ end
309
+
310
+ # 感情表(ポジティブ)
311
+ POSITIVE_EMOTION_TABLE = DiceTable::RangeTable.new(
312
+ '感情表(ポジティブ)',
313
+ '1D100',
314
+ [
315
+ # [0, '傾倒(けいとう)'],
316
+ [1..5, '好奇心(こうきしん)'],
317
+ [6..10, '憧憬(どうけい)'],
318
+ [11..15, '尊敬(そんけい)'],
319
+ [16..20, '連帯感(れんたいかん)'],
320
+ [21..25, '慈愛(じあい)'],
321
+ [26..30, '感服(かんぷく)'],
322
+ [31..35, '純愛(じゅんあい)'],
323
+ [36..40, '友情(ゆうじょう)'],
324
+ [41..45, '慕情(ぼじょう)'],
325
+ [46..50, '同情(どうじょう)'],
326
+ [51..55, '遺志(いし)'],
327
+ [56..60, '庇護(ひご)'],
328
+ [61..65, '幸福感(こうふくかん)'],
329
+ [66..70, '信頼(しんらい)'],
330
+ [71..75, '執着(しゅうちゃく)'],
331
+ [76..80, '親近感(しんきんかん)'],
332
+ [81..85, '誠意(せいい)'],
333
+ [86..90, '好意(こうい)'],
334
+ [91..95, '有為(ゆうい)'],
335
+ [96..100, '尽力(じんりょく)'],
336
+ # [101, '懐旧(かいきゅう)'],
337
+ # [102, '任意(にんい)'],
338
+ ]
339
+ ).freeze
340
+
341
+ # 感情表(ネガティブ)
342
+ NEGATIVE_EMOTION_TABLE = DiceTable::RangeTable.new(
343
+ '感情表(ネガティブ)',
344
+ '1D100',
345
+ [
346
+ # [0, '侮蔑(ぶべつ)'],
347
+ [1..5, '食傷(しょくしょう)'],
348
+ [6..10, '脅威(きょうい)'],
349
+ [11..15, '嫉妬(しっと)'],
350
+ [16..20, '悔悟(かいご)'],
351
+ [21..25, '恐怖(きょうふ)'],
352
+ [26..30, '不安(ふあん)'],
353
+ [31..35, '劣等感(れっとうかん)'],
354
+ [36..40, '疎外感(そがいかん)'],
355
+ [41..45, '恥辱(ちじょく)'],
356
+ [46..50, '憐憫(れんびん)'],
357
+ [51..55, '偏愛(へんあい)'],
358
+ [56..60, '憎悪(ぞうお)'],
359
+ [61..65, '隔意(かくい)'],
360
+ [66..70, '嫌悪(けんお)'],
361
+ [71..75, '猜疑心(さいぎしん)'],
362
+ [76..80, '厭気(いやけ)'],
363
+ [81..85, '不信感(ふしんかん)'],
364
+ [86..90, '不快感(ふかいかん)'],
365
+ [91..95, '憤懣(ふんまん)'],
366
+ [96..100, '敵愾心(てきがいしん)'],
367
+ # [101, '無関心(むかんしん)'],
368
+ # [102, '任意(にんい)'],
369
+ ]
370
+ ).freeze
371
+ end
372
+ end
373
+ end