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,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdice/game_system/NightWizard'
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class NightWizard3rd < NightWizard
8
+ # ゲームシステム名
9
+ NAME = 'ナイトウィザード The 3rd Edition'
10
+
11
+ # ゲームシステム名の読みがな
12
+ SORT_KEY = 'ないとういさあと3'
13
+
14
+ # ゲームシステムの識別子
15
+ ID = 'NightWizard3rd'
16
+
17
+ register_prefix(['([-+]?\d+)?NW.*', '2R6.*'])
18
+
19
+ def fumble_base_number(parsed)
20
+ parsed.passive_modify_number + parsed.active_modify_number
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice/command_parser"
4
+ require "bcdice/format"
5
+
6
+ module BCDice
7
+ module GameSystem
8
+ class NightmareHunterDeep < Base
9
+ # ゲームシステムの識別子
10
+ ID = 'NightmareHunterDeep'
11
+
12
+ # ゲームシステム名
13
+ NAME = 'ナイトメアハンター=ディープ'
14
+
15
+ # ゲームシステム名の読みがな
16
+ SORT_KEY = 'ないとめあはんたあていいふ'
17
+
18
+ # ダイスボットの使い方
19
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
20
+ 判定(xD6+y>=a, xD6+y, xD6)
21
+ 出目6の個数をカウントして、その4倍を合計値に加算します。
22
+ また、宿命を獲得したか表示します。
23
+
24
+ Lv目標値 (xD6+y>=LVn, xD6+y>=NLn)
25
+ レベルで目標値を指定することができます。
26
+ LVn -> n*5+1, NLn -> n*5+5 に変換されます。
27
+ 目標値'?' (xD6+y>=?)
28
+ 目標値を '?' にすると何Lv成功か、何NL成功かを表示します。
29
+
30
+ ※判定コマンドは xD6 から始まる必要があります。また xD6 が複数あると反応しません。
31
+ INFO_MESSAGE_TEXT
32
+
33
+ register_prefix('\d+D6')
34
+
35
+ def initialize(command)
36
+ super(command)
37
+
38
+ @sort_add_dice = true
39
+ end
40
+
41
+ def eval_game_system_specific_command(command)
42
+ command = command
43
+ .sub(/Lv(\d+)/i) { (Regexp.last_match(1).to_i * 5 - 1).to_s }
44
+ .sub(/NL(\d+)/i) { (Regexp.last_match(1).to_i * 5 + 5).to_s }
45
+
46
+ parser = CommandParser.new(/^\d+D6$/)
47
+ .allow_cmp_op(nil, :>=)
48
+ .enable_question_target()
49
+ cmd = parser.parse(command)
50
+ unless cmd
51
+ return nil
52
+ end
53
+
54
+ times = cmd.command.to_i
55
+
56
+ dice_list = @randomizer.roll_barabara(times, 6).sort
57
+ dice_total = dice_list.sum()
58
+ total = dice_total + cmd.modify_number
59
+
60
+ suffix, revision = dice_revision(dice_list)
61
+ total += revision
62
+
63
+ target = cmd.question_target? ? "?" : cmd.target_number
64
+ result = result_text(total, cmd.cmp_op, target)
65
+
66
+ sequence = [
67
+ "(#{cmd})",
68
+ interim_expr(cmd, dice_total, dice_list),
69
+ expr_with_revision(dice_total + cmd.modify_number, suffix),
70
+ total,
71
+ result,
72
+ fate(dice_list),
73
+ ].compact
74
+
75
+ return sequence.join(" > ")
76
+ end
77
+
78
+ def result_text(total, cmp_op, target)
79
+ return nil unless cmp_op == :>=
80
+
81
+ if target != "?"
82
+ return total >= target ? "成功" : "失敗"
83
+ end
84
+
85
+ success_lv = (total + 1) / 5
86
+ success_nl = (total - 5) / 5
87
+
88
+ return success_lv > 0 ? "Lv#{success_lv}/NL#{success_nl}成功" : "失敗"
89
+ end
90
+
91
+ # ナイトメアハンターディープ用宿命表示
92
+ def fate(dice_list)
93
+ dice_list.count(1) > 0 ? "宿命獲得" : nil
94
+ end
95
+
96
+ def interim_expr(cmd, dice_total, dice_list)
97
+ if dice_list.size > 1 || cmd.modify_number != 0
98
+ modifier = Format.modifier(cmd.modify_number)
99
+ "#{dice_total}[#{dice_list.join(',')}]#{modifier}"
100
+ end
101
+ end
102
+
103
+ def expr_with_revision(total, suffix)
104
+ suffix ? "#{total}#{suffix}" : nil
105
+ end
106
+
107
+ def dice_revision(dice_list)
108
+ count6 = dice_list.count(6)
109
+ if count6 > 0
110
+ return "+#{count6}*4", count6 * 4
111
+ else
112
+ return nil, 0
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,274 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bcdice/dice_table/table'
4
+
5
+ module BCDice
6
+ module GameSystem
7
+ class NinjaSlayer < Base
8
+ # ゲームシステムの識別子
9
+ ID = 'NinjaSlayer'
10
+
11
+ # ゲームシステム名
12
+ NAME = 'ニンジャスレイヤーTRPG'
13
+
14
+ # ゲームシステム名の読みがな
15
+ SORT_KEY = 'にんしやすれいやあRPG'
16
+
17
+ # ダイスボットの使い方
18
+ HELP_MESSAGE = <<~MESSAGETEXT
19
+ ・通常判定 NJ
20
+  NJx[y] or NJx@y or NJx
21
+  x=判定ダイス y=難易度 省略時はNORMAL(4)
22
+  例:NJ4@H 難易度HARD、判定ダイス4で判定
23
+ ・回避判定 EV
24
+  EVx[y]/z or EVx@y/z or EVx/z or EVx[y] or EVx@y or EVx
25
+  x=判定ダイス y=難易度 z=攻撃側の成功数(省略可) 難易度を省略時はNORMAL(4)
26
+  攻撃側の成功数を指定した場合、カウンターカラテ発生時には表示
27
+  例:EV5/3 難易度NORMAL(省略時)、判定ダイス5、攻撃側の成功数3で判定
28
+ ・近接攻撃 AT
29
+  ATx[y] or ATx@y or ATx
30
+  x=判定ダイス y=難易度 省略時はNORMAL(4) サツバツ!発生時には表示
31
+  例:AT6[H] 難易度HARD,判定ダイス5で近接攻撃の判定
32
+ ・サツバツ判定 SB
33
+ ・電子戦 EL
34
+  ELx[y] or ELx@y or ELx
35
+  x=判定ダイス y=難易度 省略時はNORMAL(4)
36
+  例:EL6[H] 難易度HARD,判定ダイス5で電子戦の判定
37
+
38
+ ・難易度
39
+  KIDS=K,EASY=E,NORMAL=N,HARD=H,ULTRA HARD=UH 数字にも対応
40
+ MESSAGETEXT
41
+
42
+ # ダイスボットで使用するコマンドを配列で列挙する
43
+ register_prefix([
44
+ 'NJ\d+.*',
45
+ 'EV\d+.*',
46
+ 'AT\d+.*',
47
+ 'EL\d+.*',
48
+ 'SB'
49
+ ])
50
+
51
+ def initialize(command)
52
+ super(command)
53
+
54
+ @default_cmp_op = :>=
55
+ @default_target_number = 4
56
+ end
57
+
58
+ # 難易度の値の正規表現
59
+ DIFFICULTY_VALUE_RE = /UH|[2-6KENH]/i.freeze
60
+ # 難易度の正規表現
61
+ DIFFICULTY_RE = /\[(#{DIFFICULTY_VALUE_RE})\]|@(#{DIFFICULTY_VALUE_RE})/io.freeze
62
+
63
+ # 通常判定の正規表現
64
+ NJ_RE = /\A(S)?NJ(\d+)#{DIFFICULTY_RE}?\z/io.freeze
65
+ # 回避判定の正規表現
66
+ EV_RE = %r{\AEV(\d+)#{DIFFICULTY_RE}?(?:/(\d+))?\z}io.freeze
67
+ # 近接攻撃の正規表現
68
+ AT_RE = /\AAT(\d+)#{DIFFICULTY_RE}?\z/io.freeze
69
+ # 電子戦の正規表現
70
+ EL_RE = /\AEL(\d+)#{DIFFICULTY_RE}?\z/io.freeze
71
+
72
+ # バラバラロール結果の "(" の前までの先頭部分
73
+ B_ROLL_RESULT_HEAD_RE = /\A[^(]+/.freeze
74
+
75
+ # 回避判定のノード
76
+ EV = Struct.new(:num, :difficulty, :targetValue)
77
+ # 近接攻撃のノード
78
+ AT = Struct.new(:num, :difficulty)
79
+ # 電子戦のノード
80
+ EL = Struct.new(:num, :difficulty)
81
+
82
+ # 難易度の文字表現から整数値への対応
83
+ DIFFICULTY_SYMBOL_TO_INTEGER = {
84
+ 'K' => 2,
85
+ 'E' => 3,
86
+ 'N' => 4,
87
+ 'H' => 5,
88
+ 'UH' => 6
89
+ }.freeze
90
+
91
+ def change_text(str)
92
+ m = NJ_RE.match(str)
93
+ return str unless m
94
+
95
+ b_roll = bRollCommand(m[2], integerValueOfDifficulty(m[3] || m[4]))
96
+ return "#{m[1]}#{b_roll}"
97
+ end
98
+
99
+ def eval_game_system_specific_command(command)
100
+ debug('eval_game_system_specific_command begin string', command)
101
+
102
+ if (table = TABLES[command])
103
+ return table.roll(randomizer)
104
+ end
105
+
106
+ case node = parse(command)
107
+ when EV
108
+ return executeEV(node)
109
+ when AT
110
+ return executeAT(node)
111
+ when EL
112
+ return executeEL(node)
113
+ else
114
+ return nil
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ # 構文解析する
121
+ # @param [String] command コマンド文字列
122
+ # @return [EV, AT, EL, nil]
123
+ def parse(command)
124
+ case command
125
+ when EV_RE
126
+ return parseEV(Regexp.last_match)
127
+ when AT_RE
128
+ return parseAT(Regexp.last_match)
129
+ when EL_RE
130
+ return parseEL(Regexp.last_match)
131
+ else
132
+ return nil
133
+ end
134
+ end
135
+
136
+ # 正規表現のマッチ情報から回避判定ノードを作る
137
+ # @param [MatchData] m 正規表現のマッチ情報
138
+ # @return [EV]
139
+ def parseEV(m)
140
+ num = m[1].to_i
141
+ difficulty = integerValueOfDifficulty(m[2] || m[3])
142
+ targetValue = m[4]&.to_i
143
+
144
+ return EV.new(num, difficulty, targetValue)
145
+ end
146
+
147
+ # 正規表現のマッチ情報から近接攻撃ノードを作る
148
+ # @param [MatchData] m 正規表現のマッチ情報
149
+ # @return [AT]
150
+ def parseAT(m)
151
+ num = m[1].to_i
152
+ difficulty = integerValueOfDifficulty(m[2] || m[3])
153
+
154
+ return AT.new(num, difficulty)
155
+ end
156
+
157
+ # 正規表現のマッチ情報から電子戦ノードを作る
158
+ # @param [MatchData] m 正規表現のマッチ情報
159
+ # @return [EL]
160
+ def parseEL(m)
161
+ num = m[1].to_i
162
+ difficulty = integerValueOfDifficulty(m[2] || m[3])
163
+
164
+ return EL.new(num, difficulty)
165
+ end
166
+
167
+ # 回避判定を行う
168
+ # @param [EV] ev 回避判定ノード
169
+ # @return [String] 回避判定結果
170
+ def executeEV(ev)
171
+ command = bRollCommand(ev.num, ev.difficulty)
172
+
173
+ rollResult = BCDice::CommonCommand::BarabaraDice.new(command, @randomizer, self).eval().sub(B_ROLL_RESULT_HEAD_RE, '')
174
+ return rollResult unless ev.targetValue
175
+
176
+ m = /成功数(\d+)/.match(rollResult)
177
+ raise '成功数が見つかりません' unless m
178
+
179
+ numOfSuccesses = m[1].to_i
180
+ if numOfSuccesses > ev.targetValue
181
+ return "#{rollResult} > カウンターカラテ!!"
182
+ end
183
+
184
+ return rollResult
185
+ end
186
+
187
+ # 近接攻撃を行う
188
+ # @param [AT] at 近接攻撃ノード
189
+ # @return [String] 近接攻撃結果
190
+ def executeAT(at)
191
+ command = bRollCommand(at.num, at.difficulty)
192
+ rollResult = BCDice::CommonCommand::BarabaraDice.new(command, @randomizer, self).eval().sub(B_ROLL_RESULT_HEAD_RE, '')
193
+
194
+ # バラバラロールの出目を取得する
195
+ # TODO: バラバラロールの結果として、出目を配列で取得できるようにする
196
+ m = /> (\d+(?:,\d+)*)/.match(rollResult)
197
+ values = m[1].split(',').map(&:to_i)
198
+
199
+ numOfMaxValues = values.select { |v| v == 6 }.length
200
+
201
+ return numOfMaxValues >= 2 ? "#{rollResult} > サツバツ!!" : rollResult
202
+ end
203
+
204
+ # 電子戦を行う
205
+ # @param [EL] el 電子戦ノード
206
+ # @return [String] 電子戦結果
207
+ def executeEL(el)
208
+ command = bRollCommand(el.num, el.difficulty)
209
+ rollResult = BCDice::CommonCommand::BarabaraDice.new(command, @randomizer, self).eval().sub(B_ROLL_RESULT_HEAD_RE, '')
210
+
211
+ # バラバラロールの出目を取得する
212
+ # TODO: バラバラロールの結果として、出目を配列で取得できるようにする
213
+ m = /> (\d+(?:,\d+)*)/.match(rollResult)
214
+ values = m[1].split(',').map(&:to_i)
215
+
216
+ numOfMaxValues = values.select { |v| v == 6 }.length
217
+
218
+ sumOfTrueValues = values.select { |v| v >= el.difficulty }.length
219
+
220
+ return numOfMaxValues >= 1 ? "#{rollResult} + #{numOfMaxValues} > #{sumOfTrueValues + numOfMaxValues}" : rollResult
221
+ end
222
+
223
+ # 難易度の整数値を返す
224
+ # @param [String, nil] s 難易度表記
225
+ # @return [Integer] 難易度の整数値
226
+ # @raise [KeyError, IndexError] 無効な難易度表記が渡された場合。
227
+ #
228
+ # sは2から6までの数字あるいは'K', 'E', 'N', 'H', 'UH'。
229
+ # sがnilの場合は 4 を返す。
230
+ def integerValueOfDifficulty(s)
231
+ return 4 unless s
232
+
233
+ return s.to_i if /\A[2-6]\z/.match(s)
234
+
235
+ return DIFFICULTY_SYMBOL_TO_INTEGER.fetch(s.upcase)
236
+ end
237
+
238
+ # バラバラロールのコマンドを返す
239
+ # @param [#to_s] num ダイス数
240
+ # @param [#to_s] difficulty 難易度
241
+ # @return [String]
242
+ def bRollCommand(num, difficulty)
243
+ "#{num}B6>=#{difficulty}"
244
+ end
245
+
246
+ # サツバツ表
247
+ SATSUBATSU_TABLE = [
248
+ '「死ねーッ!」腹部に強烈な一撃! 敵はくの字に折れ曲がり、ワイヤーアクションめいて吹っ飛んだ!:本来のダメージ+1ダメージを与える。敵は後方の壁または障害物に向かって、何マスでもまっすぐ弾き飛ばされる(他のキャラのいるマスは通過する)。壁または障害物に接触した時点で、敵はさらに1ダメージを受ける。敵はこの激突ダメージに対して改めて『回避判定』を行っても良い。',
249
+ '「イヤーッ!」頭部への痛烈なカラテ! 眼球破壊もしくは激しい脳震盪が敵を襲う!:本来のダメージを与える。さらに敵の【ニューロン】と【ワザマエ】がそれぞれ1ずつ減少する(これによる最低値は1)。残虐ボーナスにより【万札】がD3発生。この攻撃を【カルマ:善】のキャラに対して行ってしまった場合、【DKK】がD3上昇する。',
250
+ '「苦しみ抜いて死ぬがいい」急所を情け容赦なく破壊!:本来のダメージ+1ダメージを与える。耐え難い苦痛により、敵は【精神力】が-2され、【ニューロン】が1減少する(これによる最低値は1)。残虐ボーナスにより【万札】がD3発生。この攻撃を【カルマ:善】のキャラに対して行ってしまった場合、【DKK】がD3上昇する。',
251
+ '「逃げられるものなら逃げてみよ」敵の脚を粉砕!:本来のダメージを与える。さらに敵の【脚力】がD3減少する(最低値は1)。残虐ボーナスにより【万札】がD3発生。この攻撃を【カルマ:善】のキャラに対して行ってしまった場合、【DKK】がD3上昇する。',
252
+ '「これで手も足も出まい!」敵の両腕を切り飛ばした! 鮮血がスプリンクラーめいて噴き出す!:本来のダメージ+1ダメージを与える。さらに敵の【ワザマエ】と【カラテ】がそれぞれ2減少する(最低値は1)。残虐ボーナスにより【万札】がD3発生。この攻撃を【カルマ:善】のキャラに対して行ってしまった場合、【DKK】がD3上昇する。',
253
+ '「イイイヤアアアアーーーーッ!」ヤリめいたチョップが敵の胸を貫通! さらに心臓を掴み取り、握りつぶした! ナムアミダブツ!:敵は残り【体力】に関係なく即死する。残虐ボーナスにより【万札】がD6発生。この攻撃を【カルマ:善】のキャラに対して行ってしまった場合、【DKK】がD6上昇する。'
254
+ ].freeze
255
+
256
+ # 表の定義
257
+ TABLES = {
258
+ 'SB' => DiceTable::Table.new(
259
+ 'サツバツ表',
260
+ '1D6',
261
+ SATSUBATSU_TABLE
262
+ )
263
+ }.freeze
264
+
265
+ # ダイスボットで使用するコマンドを配列で列挙する
266
+ register_prefix([
267
+ 'NJ\d+.*',
268
+ 'EV\d+.*',
269
+ 'AT\d+.*',
270
+ 'EL\d+.*'
271
+ ] + TABLES.keys)
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class NjslyrBattle < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'NJSLYRBATTLE'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'NJSLYRBATTLE'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'にんしやすれいやあはとる'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
17
+ ・カラテロール
18
+ 2d6<=(カラテ点)
19
+ 例)2d6<=5
20
+ (2D6<=5) > 2[1,1] > 2 > 成功 重点 3 溜まる
21
+ INFO_MESSAGE_TEXT
22
+
23
+ # ゲーム別成功度判定(2D6)
24
+ def check_2D6(total, _dice_total, dice_list, cmp_op, target)
25
+ return '' if target == '?'
26
+ return '' if cmp_op != :<=
27
+
28
+ return success_text(total, target) + juuten(dice_list)
29
+ end
30
+
31
+ def success_text(total, target)
32
+ if total <= target
33
+ " > 成功"
34
+ else
35
+ " > 失敗"
36
+ end
37
+ end
38
+
39
+ def juuten(dice_list)
40
+ juuten = dice_list.count(1) + dice_list.count(6)
41
+
42
+ if dice_list[0] == dice_list[1]
43
+ juuten += 1
44
+ end
45
+
46
+ if juuten > 0
47
+ " 重点 #{juuten} 溜まる"
48
+ else
49
+ ""
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end