bcdice 3.0.0 → 3.2.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.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +79 -2
  3. data/README.md +32 -0
  4. data/i18n/MonotoneMuseum/ja_jp.yml +3 -3
  5. data/i18n/StellarKnights/ja_jp.yml +496 -0
  6. data/lib/bcdice/common_command/add_dice.rb +1 -1
  7. data/lib/bcdice/common_command/calc.rb +1 -1
  8. data/lib/bcdice/dice_table.rb +2 -0
  9. data/lib/bcdice/dice_table/d66_half_grid_table.rb +33 -0
  10. data/lib/bcdice/dice_table/d66_one_third_table.rb +34 -0
  11. data/lib/bcdice/dice_table/sai_fic_skill_table.rb +1 -1
  12. data/lib/bcdice/game_system.rb +4 -0
  13. data/lib/bcdice/game_system/AceKillerGene.rb +1 -1
  14. data/lib/bcdice/game_system/Ainecadette.rb +68 -0
  15. data/lib/bcdice/game_system/Airgetlamh.rb +1 -1
  16. data/lib/bcdice/game_system/AlchemiaStruggle.rb +1 -1
  17. data/lib/bcdice/game_system/Alsetto.rb +1 -1
  18. data/lib/bcdice/game_system/Alshard.rb +1 -1
  19. data/lib/bcdice/game_system/AlterRaise.rb +2 -2
  20. data/lib/bcdice/game_system/AngelGear.rb +123 -0
  21. data/lib/bcdice/game_system/AnimaAnimus.rb +1 -1
  22. data/lib/bcdice/game_system/Arianrhod.rb +6 -8
  23. data/lib/bcdice/game_system/ArsMagica.rb +1 -1
  24. data/lib/bcdice/game_system/Avandner.rb +1 -1
  25. data/lib/bcdice/game_system/BBN.rb +1 -1
  26. data/lib/bcdice/game_system/BadLife.rb +1 -1
  27. data/lib/bcdice/game_system/BarnaKronika.rb +1 -1
  28. data/lib/bcdice/game_system/BattleTech.rb +1 -1
  29. data/lib/bcdice/game_system/BeastBindTrinity.rb +2 -2
  30. data/lib/bcdice/game_system/BeginningIdol.rb +5 -5
  31. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +5 -5
  32. data/lib/bcdice/game_system/BladeOfArcana.rb +1 -1
  33. data/lib/bcdice/game_system/BlindMythos.rb +1 -1
  34. data/lib/bcdice/game_system/BloodCrusade.rb +48 -49
  35. data/lib/bcdice/game_system/BloodMoon.rb +50 -8
  36. data/lib/bcdice/game_system/CardRanker.rb +10 -9
  37. data/lib/bcdice/game_system/ChaosFlare.rb +21 -15
  38. data/lib/bcdice/game_system/Chill.rb +10 -10
  39. data/lib/bcdice/game_system/Chill3.rb +9 -9
  40. data/lib/bcdice/game_system/CodeLayerd.rb +1 -1
  41. data/lib/bcdice/game_system/CrashWorld.rb +1 -1
  42. data/lib/bcdice/game_system/Cthulhu.rb +8 -4
  43. data/lib/bcdice/game_system/Cthulhu7th.rb +86 -342
  44. data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +2 -2
  45. data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +2 -2
  46. data/lib/bcdice/game_system/CthulhuTech.rb +1 -1
  47. data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +1 -1
  48. data/lib/bcdice/game_system/Cthulhu_Korean.rb +1 -1
  49. data/lib/bcdice/game_system/DarkBlaze.rb +1 -12
  50. data/lib/bcdice/game_system/DarkDaysDrive.rb +8 -7
  51. data/lib/bcdice/game_system/DeadlineHeroes.rb +2 -2
  52. data/lib/bcdice/game_system/DemonParasite.rb +5 -13
  53. data/lib/bcdice/game_system/DesperateRun.rb +1 -1
  54. data/lib/bcdice/game_system/DiceOfTheDead.rb +1 -1
  55. data/lib/bcdice/game_system/DoubleCross.rb +2 -2
  56. data/lib/bcdice/game_system/Dracurouge.rb +1 -1
  57. data/lib/bcdice/game_system/EarthDawn.rb +1 -1
  58. data/lib/bcdice/game_system/EarthDawn3.rb +1 -1
  59. data/lib/bcdice/game_system/EarthDawn4.rb +1 -1
  60. data/lib/bcdice/game_system/EclipsePhase.rb +14 -14
  61. data/lib/bcdice/game_system/Elric.rb +18 -14
  62. data/lib/bcdice/game_system/Elysion.rb +3 -3
  63. data/lib/bcdice/game_system/EmbryoMachine.rb +9 -8
  64. data/lib/bcdice/game_system/Emoklore.rb +3 -3
  65. data/lib/bcdice/game_system/EtrianOdysseySRS.rb +1 -1
  66. data/lib/bcdice/game_system/Fiasco.rb +1 -1
  67. data/lib/bcdice/game_system/FilledWith.rb +205 -1272
  68. data/lib/bcdice/game_system/FullMetalPanic.rb +1 -1
  69. data/lib/bcdice/game_system/GURPS.rb +17 -28
  70. data/lib/bcdice/game_system/Garako.rb +12 -4
  71. data/lib/bcdice/game_system/GardenOrder.rb +1 -1
  72. data/lib/bcdice/game_system/GehennaAn.rb +1 -1
  73. data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +1 -1
  74. data/lib/bcdice/game_system/GoblinSlayer.rb +1 -1
  75. data/lib/bcdice/game_system/Gorilla.rb +3 -9
  76. data/lib/bcdice/game_system/GranCrest.rb +18 -11
  77. data/lib/bcdice/game_system/Gundog.rb +9 -8
  78. data/lib/bcdice/game_system/GundogRevised.rb +10 -9
  79. data/lib/bcdice/game_system/GundogZero.rb +1 -1
  80. data/lib/bcdice/game_system/GurpsFW.rb +16 -16
  81. data/lib/bcdice/game_system/HarnMaster.rb +19 -26
  82. data/lib/bcdice/game_system/HatsuneMiku.rb +1 -1
  83. data/lib/bcdice/game_system/Hieizan.rb +12 -21
  84. data/lib/bcdice/game_system/HouraiGakuen.rb +1 -1
  85. data/lib/bcdice/game_system/HuntersMoon.rb +5 -10
  86. data/lib/bcdice/game_system/Illusio.rb +25 -34
  87. data/lib/bcdice/game_system/InfiniteFantasia.rb +19 -17
  88. data/lib/bcdice/game_system/Insane.rb +13 -20
  89. data/lib/bcdice/game_system/IthaWenUa.rb +8 -15
  90. data/lib/bcdice/game_system/JamesBond.rb +10 -10
  91. data/lib/bcdice/game_system/JekyllAndHyde.rb +1 -1
  92. data/lib/bcdice/game_system/Kamigakari.rb +1 -1
  93. data/lib/bcdice/game_system/KanColle.rb +4 -9
  94. data/lib/bcdice/game_system/KemonoNoMori.rb +1 -1
  95. data/lib/bcdice/game_system/KillDeathBusiness.rb +7 -15
  96. data/lib/bcdice/game_system/KurayamiCrying.rb +55 -2
  97. data/lib/bcdice/game_system/LogHorizon.rb +3 -3
  98. data/lib/bcdice/game_system/LostRoyal.rb +1 -1
  99. data/lib/bcdice/game_system/MeikyuDays.rb +11 -9
  100. data/lib/bcdice/game_system/MeikyuKingdom.rb +28 -28
  101. data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +5 -5
  102. data/lib/bcdice/game_system/MetalHead.rb +12 -22
  103. data/lib/bcdice/game_system/MetalHeadExtream.rb +5 -5
  104. data/lib/bcdice/game_system/MetallicGuardian.rb +1 -1
  105. data/lib/bcdice/game_system/MonotoneMuseum.rb +9 -7
  106. data/lib/bcdice/game_system/Nechronica.rb +28 -21
  107. data/lib/bcdice/game_system/NeverCloud.rb +540 -5
  108. data/lib/bcdice/game_system/NightWizard.rb +1 -1
  109. data/lib/bcdice/game_system/NightWizard3rd.rb +1 -1
  110. data/lib/bcdice/game_system/NinjaSlayer.rb +4 -13
  111. data/lib/bcdice/game_system/NjslyrBattle.rb +8 -11
  112. data/lib/bcdice/game_system/OneWayHeroics.rb +1 -1
  113. data/lib/bcdice/game_system/OracleEngine.rb +1 -1
  114. data/lib/bcdice/game_system/OrgaRain.rb +17 -25
  115. data/lib/bcdice/game_system/Paradiso.rb +3 -3
  116. data/lib/bcdice/game_system/ParanoiaRebooted.rb +1 -1
  117. data/lib/bcdice/game_system/ParasiteBlood.rb +1 -1
  118. data/lib/bcdice/game_system/Peekaboo.rb +4 -9
  119. data/lib/bcdice/game_system/Pendragon.rb +7 -7
  120. data/lib/bcdice/game_system/PhantasmAdventure.rb +8 -8
  121. data/lib/bcdice/game_system/Postman.rb +2 -2
  122. data/lib/bcdice/game_system/PulpCthulhu.rb +1 -1
  123. data/lib/bcdice/game_system/Raisondetre.rb +2 -2
  124. data/lib/bcdice/game_system/RecordOfLodossWar.rb +1 -1
  125. data/lib/bcdice/game_system/RecordOfSteam.rb +1 -1
  126. data/lib/bcdice/game_system/Revulture.rb +123 -0
  127. data/lib/bcdice/game_system/RokumonSekai2.rb +1 -1
  128. data/lib/bcdice/game_system/RuneQuest.rb +8 -8
  129. data/lib/bcdice/game_system/Ryutama.rb +1 -1
  130. data/lib/bcdice/game_system/SRS.rb +1 -1
  131. data/lib/bcdice/game_system/SamsaraBallad.rb +1 -1
  132. data/lib/bcdice/game_system/Satasupe.rb +79 -860
  133. data/lib/bcdice/game_system/ScreamHighSchool.rb +2 -2
  134. data/lib/bcdice/game_system/SevenFortressMobius.rb +1 -1
  135. data/lib/bcdice/game_system/SharedFantasia.rb +20 -24
  136. data/lib/bcdice/game_system/ShinkuuGakuen.rb +2 -2
  137. data/lib/bcdice/game_system/ShinobiGami.rb +17 -9
  138. data/lib/bcdice/game_system/Skynauts.rb +4 -4
  139. data/lib/bcdice/game_system/SkynautsBouken.rb +228 -0
  140. data/lib/bcdice/game_system/SteamPunkers.rb +1 -1
  141. data/lib/bcdice/game_system/StellarKnights.rb +59 -696
  142. data/lib/bcdice/game_system/SterileLife.rb +2 -3
  143. data/lib/bcdice/game_system/StrangerOfSwordCity.rb +2 -2
  144. data/lib/bcdice/game_system/StratoShout.rb +8 -16
  145. data/lib/bcdice/game_system/Strave.rb +1 -1
  146. data/lib/bcdice/game_system/SwordWorld.rb +58 -185
  147. data/lib/bcdice/game_system/SwordWorld2_0.rb +22 -150
  148. data/lib/bcdice/game_system/SwordWorld2_5.rb +127 -41
  149. data/lib/bcdice/game_system/TherapieSein.rb +1 -1
  150. data/lib/bcdice/game_system/TokyoGhostResearch.rb +1 -1
  151. data/lib/bcdice/game_system/Torg.rb +1 -1
  152. data/lib/bcdice/game_system/TorgEternity.rb +2 -2
  153. data/lib/bcdice/game_system/TrinitySeven.rb +4 -4
  154. data/lib/bcdice/game_system/TunnelsAndTrolls.rb +1 -1
  155. data/lib/bcdice/game_system/TwilightGunsmoke.rb +1 -1
  156. data/lib/bcdice/game_system/UnsungDuet.rb +1 -1
  157. data/lib/bcdice/game_system/Utakaze.rb +1 -1
  158. data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +1 -1
  159. data/lib/bcdice/game_system/Villaciel.rb +1 -1
  160. data/lib/bcdice/game_system/WARPS.rb +11 -9
  161. data/lib/bcdice/game_system/WaresBlade.rb +4 -9
  162. data/lib/bcdice/game_system/Warhammer.rb +16 -7
  163. data/lib/bcdice/game_system/Warhammer4.rb +16 -12
  164. data/lib/bcdice/game_system/WitchQuest.rb +1 -1
  165. data/lib/bcdice/game_system/WorldOfDarkness.rb +1 -1
  166. data/lib/bcdice/game_system/YankeeYogSothoth.rb +4 -9
  167. data/lib/bcdice/game_system/YearZeroEngine.rb +1 -1
  168. data/lib/bcdice/game_system/ZettaiReido.rb +1 -1
  169. data/lib/bcdice/game_system/cthulhu7th/full_auto.rb +294 -0
  170. data/lib/bcdice/game_system/cthulhu7th/rollable.rb +41 -0
  171. data/lib/bcdice/game_system/filled_with/enemy_data_tables.rb +322 -0
  172. data/lib/bcdice/game_system/filled_with/event_tables.rb +392 -0
  173. data/lib/bcdice/game_system/filled_with/tresure_tables.rb +179 -0
  174. data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +1 -1
  175. data/lib/bcdice/game_system/satasupe/tables.rb +723 -0
  176. data/lib/bcdice/game_system/sword_world/rating_lexer.rb +47 -0
  177. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +99 -0
  178. data/lib/bcdice/game_system/sword_world/rating_parser.rb +457 -0
  179. data/lib/bcdice/game_system/sword_world/transcendent_test.rb +122 -0
  180. data/lib/bcdice/repl.rb +1 -1
  181. data/lib/bcdice/result.rb +26 -0
  182. data/lib/bcdice/version.rb +1 -1
  183. metadata +20 -4
@@ -37,8 +37,7 @@ module BCDice
37
37
   ・超未来の宇宙船内 INT
38
38
  MESSAGETEXT
39
39
 
40
- register_prefix('(\d+)*DA.*\[(\d+),(\d+)(,(\d+))?\]', 'VPFT', 'VNFT', 'VNRT', 'AAFT', 'AST', 'RNST', 'RET', 'TRST', 'TRAT', 'TRMT', 'TROT', 'TET', 'ENT', 'CUT', 'NAT', 'INT') # '(\d+)*DA.*\[.*\]'
41
-
40
+ register_prefix('\d*DA', 'VPFT', 'VNFT', 'VNRT', 'AAFT', 'AST', 'RNST', 'RET', 'TRST', 'TRAT', 'TRMT', 'TROT', 'TET', 'ENT', 'CUT', 'NAT', 'INT')
42
41
  def eval_game_system_specific_command(command) # ダイスロールコマンド
43
42
  # 通常判定部分をgetJudgeResultコマンドに切り分け
44
43
  output = getJudgeResult(command)
@@ -104,7 +103,7 @@ module BCDice
104
103
 
105
104
  def getJudgeResult(command)
106
105
  case command
107
- when /(\d+)*DA([\d+*\-]*\d)?\[(\d+),(\d+)(,(\d+))?\]/i
106
+ when /(\d+)?DA([\d+*\-]*\d)?\[(\d+),(\d+)(,(\d+))?\]/i
108
107
  number = (Regexp.last_match(1) || 1).to_i
109
108
  correction = (Regexp.last_match(2) || 0).to_i
110
109
  single = (Regexp.last_match(3) || 4).to_i
@@ -10,7 +10,7 @@ module BCDice
10
10
  NAME = '剣の街の異邦人TRPG'
11
11
 
12
12
  # ゲームシステム名の読みがな
13
- SORT_KEY = 'けんのまちのいほうしんTRPG'
13
+ SORT_KEY = 'つるきのまちのいほうしんTRPG'
14
14
 
15
15
  # ダイスボットの使い方
16
16
  HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
@@ -21,7 +21,7 @@ module BCDice
21
21
  ・D66ダイスあり
22
22
  INFO_MESSAGE_TEXT
23
23
 
24
- register_prefix('\d+SR.*')
24
+ register_prefix('\d+SR')
25
25
 
26
26
  def initialize(command)
27
27
  super(command)
@@ -32,22 +32,14 @@ module BCDice
32
32
  @d66_sort_type = D66SortType::ASC
33
33
  end
34
34
 
35
- def check_2D6(total, dice_total, _dice_list, cmp_op, target)
36
- return '' if target == '?'
37
- return '' unless cmp_op == :>=
38
-
39
- result =
40
- if dice_total <= 2
41
- translate("StratoShout.fumble")
42
- elsif dice_total >= 12
43
- translate("StratoShout.critical")
44
- elsif total >= target
45
- translate("success")
46
- else
47
- translate("failure")
48
- end
49
-
50
- return " > #{result}"
35
+ def result_2d6(_total, dice_total, _dice_list, cmp_op, _target)
36
+ return nil unless cmp_op == :>=
37
+
38
+ if dice_total <= 2
39
+ Result.fumble(translate("StratoShout.fumble"))
40
+ elsif dice_total >= 12
41
+ Result.critical(translate("StratoShout.critical"))
42
+ end
51
43
  end
52
44
 
53
45
  def eval_game_system_specific_command(command)
@@ -33,7 +33,7 @@ module BCDice
33
33
  MESSAGETEXT
34
34
 
35
35
  register_prefix(
36
- 'MP\d+', '\d+ST\d+(x|\*)\d+',
36
+ 'MP', '\d+ST',
37
37
  'AFF', 'IDT', 'AFV', 'IDV'
38
38
  )
39
39
 
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bcdice/base"
4
+ require "bcdice/game_system/sword_world/rating_parser"
5
+
3
6
  module BCDice
4
7
  module GameSystem
5
8
  class SwordWorld < Base
@@ -7,7 +10,7 @@ module BCDice
7
10
  ID = 'SwordWorld'
8
11
 
9
12
  # ゲームシステム名
10
- NAME = 'ソードワールドRPG'
13
+ NAME = 'ソード・ワールドRPG'
11
14
 
12
15
  # ゲームシステム名の読みがな
13
16
  SORT_KEY = 'そおとわあると'
@@ -15,35 +18,13 @@ module BCDice
15
18
  # ダイスボットの使い方
16
19
  HELP_MESSAGE = "・SW レーティング表 (Kx[c]+m$f) (x:キー, c:クリティカル値, m:ボーナス, f:出目修正)\n"
17
20
 
18
- register_prefix('H?K\d+.*')
21
+ register_prefix('H?K')
19
22
 
20
23
  def initialize(command)
21
24
  super(command)
22
25
  @rating_table = 0
23
26
  end
24
27
 
25
- # change_textで使うレーティング表コマンドの正規表現
26
- #
27
- # SW 2.5のダイスボットでも必要なため、共通化のために定数として定義する
28
- RATING_TABLE_RE_FOR_CHANGE_TEXT = /\AS?H?K\d+/i.freeze
29
-
30
- # コマンド実行前にメッセージを置換する
31
- # @param [String] string 受信したメッセージ
32
- # @return [String]
33
- def replace_text(string)
34
- return string unless RATING_TABLE_RE_FOR_CHANGE_TEXT.match?(string)
35
-
36
- string
37
- .gsub(/\[(\d+)\]/) { "c[#{Regexp.last_match(1)}]" }
38
- .gsub(/@(\d+)/) { "c[#{Regexp.last_match(1)}]" }
39
- .gsub(/\$([-+]?\d+)/) { "m[#{Regexp.last_match(1)}]" }
40
- .gsub(/r([-+]?\d+)/i) { "r[#{Regexp.last_match(1)}]" }
41
- end
42
-
43
- def getRatingCommandStrings
44
- "cmCM"
45
- end
46
-
47
28
  def result_2d6(total, dice_total, _dice_list, cmp_op, target)
48
29
  if dice_total >= 12
49
30
  Result.critical("自動的成功")
@@ -64,60 +45,32 @@ module BCDice
64
45
 
65
46
  private
66
47
 
48
+ def rating_parser
49
+ return RatingParser.new
50
+ end
51
+
67
52
  #################### SWレーティング表 ########################
68
53
  def rating(string) # レーティング表
69
- string = replace_text(string)
70
54
  debug("rating string", string)
55
+ command = rating_parser.parse(string)
71
56
 
72
- commands = getRatingCommandStrings
73
-
74
- m = /^S?(H?K[\d+\-]+([#{commands}]\[([\d+\-]+)\])*([\d+\-]*)([CMR]\[([\d+\-]+)\]|GF|H)*)/i.match(string)
75
- unless m
57
+ unless command
76
58
  debug("not matched")
77
59
  return '1'
78
60
  end
79
61
 
80
- string = m[1]
81
- half = string.include?("H")
82
-
83
- rateUp, string = getRateUpFromString(string)
84
- crit, string = getCriticalFromString(string, half)
85
- firstDiceChanteTo, firstDiceChangeModify, string = getDiceChangesFromString(string)
86
-
87
- key, addValue = getKeyAndAddValueFromString(string)
88
-
89
- return '1' unless key =~ /(\d+)/
90
-
91
- key = Regexp.last_match(1).to_i
92
-
93
62
  # 2.0対応
94
63
  rate_sw2_0 = getSW2_0_RatingTable
95
64
 
96
65
  keyMax = rate_sw2_0.length - 1
97
66
  debug("keyMax", keyMax)
98
- if key > keyMax
67
+ if command.rate > keyMax
99
68
  return "キーナンバーは#{keyMax}までです"
100
69
  end
101
70
 
102
71
  newRates = getNewRates(rate_sw2_0)
103
72
 
104
- output = "KeyNo.#{key}"
105
-
106
- output += "c[#{crit}]" if crit < 13
107
- output += "m[#{firstDiceChangeModify}]" if firstDiceChangeModify != 0
108
- output += "m[#{firstDiceChanteTo}]" if firstDiceChanteTo != 0
109
- output += "r[#{rateUp}]" if rateUp != 0
110
-
111
- output, values = getAdditionalString(string, output)
112
-
113
- debug('output', output)
114
-
115
- if addValue != 0
116
- output += "+#{addValue}" if addValue > 0
117
- output += addValue.to_s if addValue < 0
118
- end
119
-
120
- output += " > "
73
+ output = "#{command}"
121
74
 
122
75
  diceResultTotals = []
123
76
  diceResults = []
@@ -126,17 +79,19 @@ module BCDice
126
79
  diceOnlyTotal = 0
127
80
  totalValue = 0
128
81
  round = 0
82
+ first_to = command.first_to
83
+ first_modify = command.first_modify
129
84
 
130
85
  loop do
131
- dice_raw, diceText = rollDice(values)
86
+ dice_raw, diceText = rollDice(command)
132
87
  dice = dice_raw
133
88
 
134
- if firstDiceChanteTo != 0
135
- dice = dice_raw = firstDiceChanteTo
136
- firstDiceChanteTo = 0
137
- elsif firstDiceChangeModify != 0
138
- dice += firstDiceChangeModify.to_i
139
- firstDiceChangeModify = 0
89
+ if first_to != 0
90
+ dice = dice_raw = first_to
91
+ first_to = 0
92
+ elsif first_modify != 0
93
+ dice += first_modify
94
+ first_modify = 0
140
95
  end
141
96
 
142
97
  # 出目がピンゾロの時にはそこで終了
@@ -149,12 +104,12 @@ module BCDice
149
104
  break
150
105
  end
151
106
 
152
- dice += getAdditionalDiceValue(dice, values)
107
+ dice += command.kept_modify if (command.kept_modify != 0) && (dice != 2)
153
108
 
154
109
  dice = 2 if dice < 2
155
110
  dice = 12 if dice > 12
156
111
 
157
- currentKey = [key + round * rateUp, keyMax].min
112
+ currentKey = [command.rate + round * command.rateup, keyMax].min
158
113
  debug("currentKey", currentKey)
159
114
  rateValue = newRates[dice][currentKey]
160
115
  debug("rateValue", rateValue)
@@ -168,77 +123,20 @@ module BCDice
168
123
 
169
124
  round += 1
170
125
 
171
- break unless dice >= crit
126
+ break unless dice >= command.critical
172
127
  end
173
128
 
174
- output += getResultText(totalValue, addValue, diceResults, diceResultTotals,
175
- rateResults, diceOnlyTotal, round, half)
176
-
177
- return output
178
- end
179
-
180
- def getAdditionalString(_string, output)
181
- values = {}
182
- return output, values
183
- end
184
-
185
- def getAdditionalDiceValue(_dice, _values)
186
- 0
187
- end
188
-
189
- def getCriticalFromString(string, half)
190
- crit = half ? 13 : 10
129
+ result_text, critical, fumble = getResultText(
130
+ totalValue, command, diceResults, diceResultTotals,
131
+ rateResults, diceOnlyTotal, round
132
+ )
133
+ output += result_text
191
134
 
192
- regexp = /c\[(\d+)\]/i
193
-
194
- if regexp =~ string
195
- crit = Regexp.last_match(1).to_i
196
- crit = 3 if crit < 3 # エラートラップ(クリティカル値が3未満なら3とする)
197
- string = string.gsub(regexp, '')
135
+ return Result.new.tap do |r|
136
+ r.text = output
137
+ r.critical = critical
138
+ r.fumble = fumble
198
139
  end
199
-
200
- return crit, string
201
- end
202
-
203
- def getDiceChangesFromString(string)
204
- firstDiceChanteTo = 0
205
- firstDiceChangeModify = 0
206
-
207
- regexp = /m\[([\d+\-]+)\]/i
208
-
209
- if regexp =~ string
210
- firstDiceChangeModify = Regexp.last_match(1)
211
-
212
- unless /[+\-]/ =~ firstDiceChangeModify
213
- firstDiceChanteTo = firstDiceChangeModify.to_i
214
- firstDiceChangeModify = 0
215
- end
216
-
217
- string = string.gsub(regexp, '')
218
- end
219
-
220
- return firstDiceChanteTo, firstDiceChangeModify, string
221
- end
222
-
223
- def getRateUpFromString(string)
224
- rateUp = 0
225
- return rateUp, string
226
- end
227
-
228
- def getKeyAndAddValueFromString(string)
229
- key = nil
230
- addValue = 0
231
-
232
- if /K(\d+)([\d+\-]*)/i =~ string # ボーナスの抽出
233
- key = Regexp.last_match(1)
234
- if Regexp.last_match(2)
235
- addValue = ArithmeticEvaluator.eval(Regexp.last_match(2))
236
- end
237
- else
238
- key = string
239
- end
240
-
241
- return key, addValue
242
140
  end
243
141
 
244
142
  def getSW2_0_RatingTable
@@ -397,7 +295,7 @@ module BCDice
397
295
  return newRates
398
296
  end
399
297
 
400
- def rollDice(_values)
298
+ def rollDice(_command)
401
299
  dice_list = @randomizer.roll_barabara(2, 6)
402
300
  total = dice_list.sum()
403
301
  dice_str = dice_list.join(",")
@@ -405,15 +303,15 @@ module BCDice
405
303
  end
406
304
 
407
305
  # @param rating_total [Integer]
408
- # @param modifier [Integer]
306
+ # @param command [SwordWorld::RatingParsed]
409
307
  # @param diceResults [Array<String>]
410
308
  # @param diceResultTotals [Array<String>]
411
309
  # @param rateResults [Array<String>]
412
310
  # @param dice_total [Integer]
413
311
  # @param round [Integer]
414
- # @param half [Boolean]
415
- def getResultText(rating_total, modifier, diceResults, diceResultTotals,
416
- rateResults, dice_total, round, half)
312
+ # @return [Array(String, Boolean, Boolean)] output, critical, fumble
313
+ def getResultText(rating_total, command, diceResults, diceResultTotals,
314
+ rateResults, dice_total, round)
417
315
  sequence = []
418
316
 
419
317
  sequence.push("2D:[#{diceResults.join(' ')}]=#{diceResultTotals.join(',')}")
@@ -421,18 +319,25 @@ module BCDice
421
319
  if dice_total <= 2
422
320
  sequence.push(rateResults.join(','))
423
321
  sequence.push("自動的失敗")
424
- return sequence.join(" > ")
322
+ return sequence.join(" > "), false, true
425
323
  end
426
324
 
427
325
  # rate回数が1回で、修正値がない時には途中式と最終結果が一致するので、途中式を省略する
428
- if rateResults.size > 1 || modifier != 0
429
- text = rateResults.join(',') + Format.modifier(modifier)
430
- if half
326
+ if rateResults.size > 1 || command.modifier != 0
327
+ text = rateResults.join(',') + Format.modifier(command.modifier)
328
+ if command.half
431
329
  text = "(#{text})/2"
330
+ if command.modifier_after_half != 0
331
+ text += Format.modifier(command.modifier_after_half)
332
+ end
333
+ end
334
+ sequence.push(text)
335
+ elsif command.half
336
+ text = "#{rateResults.first}/2"
337
+ if command.modifier_after_half != 0
338
+ text += Format.modifier(command.modifier_after_half)
432
339
  end
433
340
  sequence.push(text)
434
- elsif half
435
- sequence.push("#{rateResults.first}/2")
436
341
  end
437
342
 
438
343
  if round > 1
@@ -440,50 +345,18 @@ module BCDice
440
345
  sequence.push(round_text)
441
346
  end
442
347
 
443
- total = rating_total + modifier
444
- if half
348
+ total = rating_total + command.modifier
349
+ if command.half
445
350
  total = (total / 2.0).ceil
351
+ if command.modifier_after_half != 0
352
+ total += command.modifier_after_half
353
+ end
446
354
  end
447
355
 
448
356
  total_text = total.to_s
449
357
  sequence.push(total_text)
450
358
 
451
- return sequence.join(" > ")
452
- end
453
-
454
- def setRatingTable(tnick)
455
- mode_str = ""
456
- pre_mode = @rating_table
457
-
458
- if /(\d+)/ =~ tnick
459
- @rating_table = Regexp.last_match(1).to_i
460
- if @rating_table > 1
461
- mode_str = "2.0-mode"
462
- @rating_table = 2
463
- elsif @rating_table > 0
464
- mode_str = "new-mode"
465
- @rating_table = 1
466
- else
467
- mode_str = "old-mode"
468
- @rating_table = 0
469
- end
470
- else
471
- case tnick
472
- when /old/i
473
- @rating_table = 0
474
- mode_str = "old-mode"
475
- when /new/i
476
- @rating_table = 1
477
- mode_str = "new-mode"
478
- when /2\.0/i
479
- @rating_table = 2
480
- mode_str = "2.0-mode"
481
- end
482
- end
483
-
484
- return '1' if @rating_table == pre_mode
485
-
486
- return "RatingTableを#{mode_str}に変更しました"
359
+ return sequence.join(" > "), round > 1, false
487
360
  end
488
361
  end
489
362
  end
@@ -3,6 +3,7 @@
3
3
  require 'bcdice/arithmetic_evaluator'
4
4
 
5
5
  require 'bcdice/game_system/SwordWorld'
6
+ require 'bcdice/game_system/sword_world/transcendent_test'
6
7
 
7
8
  module BCDice
8
9
  module GameSystem
@@ -11,7 +12,7 @@ module BCDice
11
12
  ID = 'SwordWorld2.0'
12
13
 
13
14
  # ゲームシステム名
14
- NAME = 'ソードワールド2.0'
15
+ NAME = 'ソード・ワールド2.0'
15
16
 
16
17
  # ゲームシステム名の読みがな
17
18
  SORT_KEY = 'そおとわあると2.0'
@@ -34,10 +35,12 @@ module BCDice
34
35
   またタイプの軽減化のために末尾に「@クリティカル値」でも処理するようにしました。
35
36
   例)K20[10]   K10+5[9]   k30[10]   k10[9]+10   k10-5@9
36
37
 
37
- ・レーティング表の半減 (HKx)
38
+ ・レーティング表の半減 (HKx, KxH+N)
38
39
   レーティング表の先頭または末尾に"H"をつけると、レーティング表を振って最終結果を半減させます。
40
+  末尾につけた場合、直後に修正ををつけることで、半減後の加減算を行うことができます。
41
+  この際、複数の項による修正にはカッコで囲うことが必要です(カッコがないとパースに失敗します)
39
42
   クリティカル値を指定しない場合、クリティカルなしと扱われます。
40
-  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH
43
+  例)HK20  K20h  HK10-5@9  K10-5@9H  K20gfH  K20+8H+2  K20+8H(1+1)
41
44
 
42
45
  ・ダイス目の修正(運命変転やクリティカルレイ用)
43
46
   末尾に「$修正値」でダイス目に修正がかかります。
@@ -65,115 +68,13 @@ module BCDice
65
68
   絡み効果表を出すことができます。
66
69
  INFO_MESSAGE_TEXT
67
70
 
68
- register_prefix('H?K\d+.*', 'Gr(\d+)?', '2D6?@\d+.*', 'FT', 'TT')
69
-
70
- # 超越判定のノード
71
- class TranscendentTest
72
- # @param [Integer] critical_value クリティカル値
73
- # @param [Integer] modifier 修正値
74
- # @param [String, nil] cmp_op 比較演算子(> または >=)
75
- # @param [Integer, nil] target 目標値
76
- def initialize(critical_value, modifier, cmp_op, target)
77
- @critical_value = critical_value
78
- @modifier = modifier
79
- @cmp_op = cmp_op
80
- @target = target
81
-
82
- @modifier_str = Format.modifier(@modifier)
83
- @expression = node_expression()
84
- end
85
-
86
- # 超越判定を行う
87
- # @param randomizer [Randomizer]
88
- # @return [String]
89
- def execute(randomizer)
90
- if @critical_value < 3
91
- return "(#{@expression}) > クリティカル値が小さすぎます。3以上を指定してください。"
92
- end
93
-
94
- first_value_group = randomizer.roll_barabara(2, 6)
95
- value_groups = [first_value_group]
96
-
97
- fumble = first_value_group == [1, 1]
98
- critical = first_value_group == [6, 6]
99
-
100
- if !fumble && !critical
101
- while sum_of_dice(value_groups.last) >= @critical_value
102
- value_groups.push(randomizer.roll_barabara(2, 6))
103
- end
104
- end
105
-
106
- sum = sum_of_dice(value_groups)
107
- total_sum = sum + @modifier
108
-
109
- parts = [
110
- "(#{@expression})",
111
- "#{dice_str(value_groups, sum)}#{@modifier_str}",
112
- total_sum,
113
- @target && result_str(total_sum, value_groups.length, fumble, critical)
114
- ].compact
115
-
116
- return parts.join(' > ')
117
- end
118
-
119
- private
120
-
121
- # 数式表記を返す
122
- # @return [String]
123
- def node_expression
124
- lhs = "2D6@#{@critical_value}#{@modifier_str}"
125
-
126
- return @target ? "#{lhs}#{@cmp_op}#{@target}" : lhs
127
- end
128
-
129
- # 出目の合計を返す
130
- # @param [(Integer, Integer), Array<(Integer, Integer)>] value_groups
131
- # 出目のグループまたはその配列
132
- # @return [Integer]
133
- def sum_of_dice(value_groups)
134
- value_groups.flatten.sum
135
- end
136
-
137
- # ダイス部分の文字列を返す
138
- # @param [Array<(Integer, Integer)>] value_groups 出目のグループの配列
139
- # @param [Integer] sum 出目の合計
140
- # @return [String]
141
- def dice_str(value_groups, sum)
142
- value_groups_str =
143
- value_groups
144
- .map { |values| "[#{values.join(',')}]" }
145
- .join
146
-
147
- return "#{sum}#{value_groups_str}"
148
- end
149
-
150
- # 判定結果の文字列を返す
151
- # @param [Integer] total_sum 合計値
152
- # @param [Integer] n_value_groups 出目のグループの数
153
- # @param [Boolean] fumble ファンブルかどうか
154
- # @param [Boolean] critical クリティカルかどうか
155
- # @return [String]
156
- def result_str(total_sum, n_value_groups, fumble, critical)
157
- return '自動的失敗' if fumble
158
- return '自動的成功' if critical
159
-
160
- if total_sum.send(@cmp_op, @target)
161
- # 振り足しが行われ、合計値が41以上ならば「超成功」
162
- n_value_groups >= 2 && total_sum >= 41 ? '超成功' : '成功'
163
- else
164
- '失敗'
165
- end
166
- end
167
- end
71
+ register_prefix('H?K', 'Gr', '2D6?@\d+', 'FT', 'TT')
168
72
 
169
73
  def initialize(command)
170
74
  super(command)
171
75
  @rating_table = 2
172
76
  end
173
77
 
174
- # 超越判定のパターン
175
- TRANSCENDENT_TEST_RE = /\A2D6?@(\d+)([-+\d]+)?(?:(>=?)(\d+))?/.freeze
176
-
177
78
  def eval_game_system_specific_command(command)
178
79
  case command
179
80
  when /^Gr(\d+)?/i
@@ -182,15 +83,17 @@ module BCDice
182
83
  else
183
84
  growth
184
85
  end
185
- when TRANSCENDENT_TEST_RE
186
- m = Regexp.last_match
187
-
188
- critical_value = m[1].to_i
189
- modifier = m[2] ? ArithmeticEvaluator.eval(m[2]) : 0
190
- cmp_op = m[3]
191
- target = m[3] && m[4].to_i
86
+ when /^2D6?@\d+/i
87
+ transcendent_parser = Command::Parser.new(/2D6?/i, round_type: BCDice::RoundType::CEIL)
88
+ .enable_critical
89
+ .restrict_cmp_op_to(nil, :>=, :>)
90
+ cmd = transcendent_parser.parse(command)
91
+
92
+ unless cmd
93
+ return nil
94
+ end
192
95
 
193
- node = TranscendentTest.new(critical_value, modifier, cmp_op, target)
96
+ node = TranscendentTest.new(cmd.critical, cmd.modify_number, cmd.cmp_op, cmd.target_number)
194
97
  node.execute(@randomizer)
195
98
  when 'FT'
196
99
  get_fumble_table
@@ -201,32 +104,13 @@ module BCDice
201
104
  end
202
105
  end
203
106
 
204
- def getRateUpFromString(string)
205
- rateUp = 0
206
-
207
- regexp = /r\[(\d+)\]/i
208
- if (m = regexp.match(string))
209
- rateUp = m[1].to_i
210
- string = string.gsub(regexp, '')
211
- end
212
-
213
- return rateUp, string
214
- end
215
-
216
- def getAdditionalString(string, output)
217
- output, values = super(string, output)
218
-
219
- isGratestFortune, = getGratestFortuneFromString(string)
220
-
221
- values['isGratestFortune'] = isGratestFortune
222
- output += "gf" if isGratestFortune
223
-
224
- return output, values
107
+ def rating_parser
108
+ return RatingParser.new(version: :v2_0)
225
109
  end
226
110
 
227
- def rollDice(values)
228
- unless values['isGratestFortune']
229
- return super(values)
111
+ def rollDice(command)
112
+ unless command.greatest_fortune
113
+ return super(command)
230
114
  end
231
115
 
232
116
  dice = @randomizer.roll_once(6)
@@ -234,18 +118,6 @@ module BCDice
234
118
  return dice * 2, "#{dice},#{dice}"
235
119
  end
236
120
 
237
- def getGratestFortuneFromString(string)
238
- isGratestFortune = false
239
-
240
- regexp = /gf/i
241
- if regexp.match?(string)
242
- isGratestFortune = true
243
- string = string.gsub(regexp, '')
244
- end
245
-
246
- return isGratestFortune, string
247
- end
248
-
249
121
  def growth(count = 1)
250
122
  ((1..count).map { growth_step }).join " | "
251
123
  end