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
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bcdice/arithmetic_evaluator"
4
+ require "bcdice/format"
5
+ require "bcdice/normalize"
6
+
3
7
  module BCDice
4
8
  module GameSystem
5
9
  class Amadeus < Base
@@ -46,111 +50,124 @@ module BCDice
46
50
  end
47
51
 
48
52
  def eval_game_system_specific_command(command)
49
- text = amadeusDice(command)
50
- return text unless text.nil?
51
-
52
- return roll_tables(command, self.class::TABLES)
53
+ roll_amadeus(command) ||
54
+ roll_tables(command, self.class::TABLES)
53
55
  end
54
56
 
55
- def amadeusDice(command)
56
- return nil unless /^(R([A-DS])([+\-\d]*))(@(\d))?((>(=)?)([+\-\d]*))?(@(\d))?$/i =~ command
57
-
58
- commandText = Regexp.last_match(1)
59
- skillRank = Regexp.last_match(2)
60
- modifyText = Regexp.last_match(3)
61
- signOfInequality = (Regexp.last_match(7).nil? ? ">=" : Regexp.last_match(7))
62
- targetText = (Regexp.last_match(9).nil? ? "4" : Regexp.last_match(9))
63
- if nil | Regexp.last_match(5)
64
- specialNum = Regexp.last_match(5).to_i
65
- elsif nil | Regexp.last_match(11)
66
- specialNum = Regexp.last_match(11).to_i
67
- else
68
- specialNum = 6
57
+ private
58
+
59
+ def roll_amadeus(command)
60
+ m = /^R([A-DS])([+\-\d]*)(@(\d))?((>=?)([+\-\d]*))?(@(\d))?$/i.match(command)
61
+ unless m
62
+ return nil
69
63
  end
70
64
 
71
- diceCount = CHECK_DICE_COUNT[skillRank]
72
- modify = ArithmeticEvaluator.eval(modifyText)
73
- target = ArithmeticEvaluator.eval(targetText)
74
-
75
- diceList = @randomizer.roll_barabara(diceCount, 6)
76
- diceText = diceList.join(",")
77
- specialText = (specialNum == 6 ? "" : "@#{specialNum}")
78
-
79
- message = "(#{commandText}#{specialText}#{signOfInequality}#{targetText}) > [#{diceText}]#{modifyText} > "
80
- diceList = [diceList.min] if skillRank == "D"
81
- is_loop = false
82
- diceList.each do |dice|
83
- if is_loop
84
- message += " / "
85
- elsif diceList.length > 1
86
- is_loop = true
65
+ rank = m[1]
66
+ modifier = ArithmeticEvaluator.eval(m[2])
67
+ cmp_op = m[6] ? Normalize.comparison_operator(m[6]) : :>=
68
+ target = m[7] ? ArithmeticEvaluator.eval(m[7]) : 4
69
+ special = (m[4] || m[9] || 6).to_i
70
+
71
+ dice_count = CHECK_DICE_COUNT[rank]
72
+
73
+ dice_list = @randomizer.roll_barabara(dice_count, 6)
74
+ dice_text = dice_list.join(",")
75
+ special_text = (special == 6 ? "" : "@#{special}")
76
+
77
+ dice_list = [dice_list.min] if rank == "D"
78
+ available_inga = dice_list.size > 1
79
+ inga_table = translate("Amadeus.inga_table")
80
+
81
+ success = false
82
+ critical = false
83
+ fumble = false
84
+
85
+ results =
86
+ dice_list.map do |dice|
87
+ total = dice + modifier
88
+ result =
89
+ if dice == 1
90
+ fumble = true
91
+ translate("Amadeus.fumble")
92
+ elsif dice >= special
93
+ critical = true
94
+ success = true
95
+ translate("Amadeus.special")
96
+ elsif total.send(cmp_op, target)
97
+ success = true
98
+ translate("success")
99
+ else
100
+ translate("failure")
101
+ end
102
+
103
+ if available_inga
104
+ inga = inga_table[dice - 1]
105
+ "#{total}_#{result}[#{dice}#{inga}]"
106
+ else
107
+ "#{total}_#{result}[#{dice}]"
108
+ end
87
109
  end
88
- achieve = dice + modify
89
- result = check_success(achieve, dice, signOfInequality, target, specialNum)
90
- if is_loop
91
- inga_table = translate("Amadeus.inga_table")
92
- inga = inga_table[dice - 1]
93
- message += "#{achieve}_#{result}[#{dice}#{inga}]"
110
+
111
+ sequence = [
112
+ "(R#{rank}#{Format.modifier(modifier)}#{special_text}#{cmp_op}#{target})",
113
+ "[#{dice_text}]#{Format.modifier(modifier)}",
114
+ results.join(" / ")
115
+ ]
116
+
117
+ Result.new.tap do |r|
118
+ r.text = sequence.join(" > ")
119
+ if success
120
+ r.success = true
121
+ r.critical = critical
94
122
  else
95
- message += "#{achieve}_#{result}[#{dice}]"
123
+ r.failure = true
124
+ r.fumble = fumble
96
125
  end
97
126
  end
98
-
99
- return message
100
- end
101
-
102
- def check_success(total_n, dice_n, signOfInequality, diff, special_n)
103
- return translate("Amadeus.fumble") if dice_n == 1
104
- return translate("Amadeus.special") if dice_n >= special_n
105
-
106
- cmp_op = Normalize.comparison_operator(signOfInequality)
107
- target_num = diff.to_i
108
-
109
- if total_n.send(cmp_op, target_num)
110
- translate("success")
111
- else
112
- translate("failure")
113
- end
114
127
  end
115
128
 
116
129
  CHECK_DICE_COUNT = {"S" => 4, "A" => 3, "B" => 2, "C" => 1, "D" => 2}.freeze
117
130
 
118
- def self.translate_tables(locale)
119
- {
120
- "ECT" => DiceTable::Table.from_i18n("Amadeus.table.ECT", locale),
121
- "BST" => DiceTable::Table.from_i18n("Amadeus.table.BST", locale),
122
- "RT" => DiceTable::Table.from_i18n("Amadeus.table.RT", locale),
123
- "PRT" => DiceTable::Table.from_i18n("Amadeus.table.PRT", locale),
124
- "FT" => DiceTable::Table.from_i18n("Amadeus.table.FT", locale),
125
- "BT" => DiceTable::D66Table.from_i18n("Amadeus.table.BT", locale),
126
- "FWT" => DiceTable::Table.from_i18n("Amadeus.table.FWT", locale),
127
- "BRT" => DiceTable::Table.from_i18n("Amadeus.table.BRT", locale),
128
- "RIT" => DiceTable::Table.from_i18n("Amadeus.table.RIT", locale),
129
- "WT" => DiceTable::Table.from_i18n("Amadeus.table.WT", locale),
130
- "NMT" => DiceTable::Table.from_i18n("Amadeus.table.NMT", locale),
131
- "TGT" => DiceTable::Table.from_i18n("Amadeus.table.TGT", locale),
132
- "CST" => DiceTable::Table.from_i18n("Amadeus.table.CST", locale),
133
- "GCVT" => DiceTable::Table.from_i18n("Amadeus.table.GCVT", locale),
134
- "YCVT" => DiceTable::Table.from_i18n("Amadeus.table.YCVT", locale),
135
- "ECVT" => DiceTable::Table.from_i18n("Amadeus.table.ECVT", locale),
136
- "CCVT" => DiceTable::Table.from_i18n("Amadeus.table.CCVT", locale),
137
- "NCVT" => DiceTable::Table.from_i18n("Amadeus.table.NCVT", locale),
138
- "DGVT" => DiceTable::Table.from_i18n("Amadeus.table.DGVT", locale),
139
- "DAVT" => DiceTable::Table.from_i18n("Amadeus.table.DAVT", locale),
140
- "PRCT" => DiceTable::Table.from_i18n("Amadeus.table.PRCT", locale),
141
- "TCCT" => DiceTable::Table.from_i18n("Amadeus.table.TCCT", locale),
142
- "INCT" => DiceTable::Table.from_i18n("Amadeus.table.INCT", locale),
143
- "PSCT" => DiceTable::Table.from_i18n("Amadeus.table.PSCT", locale),
144
- "LVCT" => DiceTable::Table.from_i18n("Amadeus.table.LVCT", locale),
145
- "DACT" => DiceTable::Table.from_i18n("Amadeus.table.DACT", locale),
146
- "RGT" => DiceTable::Table.from_i18n("Amadeus.table.RGT", locale),
147
- "FBT" => DiceTable::Table.from_i18n("Amadeus.table.FBT", locale),
148
- "CHVT" => DiceTable::Table.from_i18n("Amadeus.table.CHVT", locale),
149
- "LCVT" => DiceTable::Table.from_i18n("Amadeus.table.LCVT", locale),
150
- "KCVT" => DiceTable::Table.from_i18n("Amadeus.table.KCVT", locale),
151
- "SAT" => DiceTable::D66Table.from_i18n("Amadeus.table.SAT", locale),
152
- "SMT" => DiceTable::D66Table.from_i18n("Amadeus.table.SMT", locale),
153
- }
131
+ class << self
132
+ private
133
+
134
+ def translate_tables(locale)
135
+ {
136
+ "ECT" => DiceTable::Table.from_i18n("Amadeus.table.ECT", locale),
137
+ "BST" => DiceTable::Table.from_i18n("Amadeus.table.BST", locale),
138
+ "RT" => DiceTable::Table.from_i18n("Amadeus.table.RT", locale),
139
+ "PRT" => DiceTable::Table.from_i18n("Amadeus.table.PRT", locale),
140
+ "FT" => DiceTable::Table.from_i18n("Amadeus.table.FT", locale),
141
+ "BT" => DiceTable::D66Table.from_i18n("Amadeus.table.BT", locale),
142
+ "FWT" => DiceTable::Table.from_i18n("Amadeus.table.FWT", locale),
143
+ "BRT" => DiceTable::Table.from_i18n("Amadeus.table.BRT", locale),
144
+ "RIT" => DiceTable::Table.from_i18n("Amadeus.table.RIT", locale),
145
+ "WT" => DiceTable::Table.from_i18n("Amadeus.table.WT", locale),
146
+ "NMT" => DiceTable::Table.from_i18n("Amadeus.table.NMT", locale),
147
+ "TGT" => DiceTable::Table.from_i18n("Amadeus.table.TGT", locale),
148
+ "CST" => DiceTable::Table.from_i18n("Amadeus.table.CST", locale),
149
+ "GCVT" => DiceTable::Table.from_i18n("Amadeus.table.GCVT", locale),
150
+ "YCVT" => DiceTable::Table.from_i18n("Amadeus.table.YCVT", locale),
151
+ "ECVT" => DiceTable::Table.from_i18n("Amadeus.table.ECVT", locale),
152
+ "CCVT" => DiceTable::Table.from_i18n("Amadeus.table.CCVT", locale),
153
+ "NCVT" => DiceTable::Table.from_i18n("Amadeus.table.NCVT", locale),
154
+ "DGVT" => DiceTable::Table.from_i18n("Amadeus.table.DGVT", locale),
155
+ "DAVT" => DiceTable::Table.from_i18n("Amadeus.table.DAVT", locale),
156
+ "PRCT" => DiceTable::Table.from_i18n("Amadeus.table.PRCT", locale),
157
+ "TCCT" => DiceTable::Table.from_i18n("Amadeus.table.TCCT", locale),
158
+ "INCT" => DiceTable::Table.from_i18n("Amadeus.table.INCT", locale),
159
+ "PSCT" => DiceTable::Table.from_i18n("Amadeus.table.PSCT", locale),
160
+ "LVCT" => DiceTable::Table.from_i18n("Amadeus.table.LVCT", locale),
161
+ "DACT" => DiceTable::Table.from_i18n("Amadeus.table.DACT", locale),
162
+ "RGT" => DiceTable::Table.from_i18n("Amadeus.table.RGT", locale),
163
+ "FBT" => DiceTable::Table.from_i18n("Amadeus.table.FBT", locale),
164
+ "CHVT" => DiceTable::Table.from_i18n("Amadeus.table.CHVT", locale),
165
+ "LCVT" => DiceTable::Table.from_i18n("Amadeus.table.LCVT", locale),
166
+ "KCVT" => DiceTable::Table.from_i18n("Amadeus.table.KCVT", locale),
167
+ "SAT" => DiceTable::D66Table.from_i18n("Amadeus.table.SAT", locale),
168
+ "SMT" => DiceTable::D66Table.from_i18n("Amadeus.table.SMT", locale),
169
+ }
170
+ end
154
171
  end
155
172
 
156
173
  TABLES = translate_tables(:ja_jp)
@@ -48,17 +48,22 @@ module BCDice
48
48
  dice_text = dice.join(",")
49
49
  modify_n = 0
50
50
  success = 0
51
-
52
51
  if skill_value
53
52
  success = dice.count { |val| val <= skill_value }
54
53
  modify_n = Arithmetic.eval(modify, RoundType::FLOOR) unless modify.empty?
55
54
  end
56
55
 
57
- output = "(#{command}) > #{success}[#{dice_text}]#{format('%+d', modify_n)} > 成功数: #{success + modify_n}"
56
+ gospel = '(福音発生)' if success + modify_n >= 100
57
+
58
+ output = "(#{command}) > #{success}[#{dice_text}]#{format('%+d', modify_n)} > 成功数: #{success + modify_n}#{gospel}"
59
+
58
60
  if success + modify_n >= 100
59
- output += "(福音発生)"
61
+ Result.critical(output)
62
+ elsif 0 < success + modify_n
63
+ Result.success(output)
64
+ else
65
+ Result.failure(output)
60
66
  end
61
- return output
62
67
  end
63
68
 
64
69
  TABLES = {
@@ -117,7 +122,7 @@ module BCDice
117
122
  )
118
123
  }.freeze
119
124
 
120
- register_prefix('(\d+)AG(\d+)?(([\+\-]\d+)*)', TABLES.keys)
125
+ register_prefix('\d+AG', TABLES.keys)
121
126
  end
122
127
  end
123
128
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'bcdice/dice_table/table'
4
4
  require 'bcdice/dice_table/range_table'
5
- require 'bcdice/arithmetic_evaluator'
5
+ require 'bcdice/arithmetic'
6
6
 
7
7
  module BCDice
8
8
  module GameSystem
@@ -32,17 +32,19 @@ module BCDice
32
32
  MESSAGETEXT
33
33
 
34
34
  def eval_game_system_specific_command(command)
35
- case command
36
- when /(\d+)AN<=(\d+([+\-]\d+)*)/i
37
- return check_action(Regexp.last_match)
38
- else
35
+ m = /(\d+)AN<=(\d+([+\-]\d+)*)/i.match(command)
36
+ if TABLES.key?(command)
39
37
  return roll_tables(command, TABLES)
38
+ elsif m
39
+ return check_action(m)
40
+ else
41
+ return nil
40
42
  end
41
43
  end
42
44
 
43
45
  def check_action(match_data)
44
- dice_cnt = ArithmeticEvaluator.eval(match_data[1])
45
- target = ArithmeticEvaluator.eval(match_data[2])
46
+ dice_cnt = Arithmetic.eval(match_data[1], RoundType::FLOOR)
47
+ target = Arithmetic.eval(match_data[2], RoundType::FLOOR)
46
48
  debug("dice_cnt", dice_cnt)
47
49
  debug("target", target)
48
50
 
@@ -52,7 +54,12 @@ module BCDice
52
54
  has_critical = dice_arr.include?(1)
53
55
  result = has_critical ? suc_cnt + 2 : suc_cnt
54
56
 
55
- return "(#{dice_cnt}B10<=#{target}) > #{dice_str} > #{result > 0 ? '成功' : '失敗'}(達成値:#{result})#{has_critical ? ' (クリティカル発生)' : ''}"
57
+ Result.new.tap do |r|
58
+ r.text = "(#{dice_cnt}B10<=#{target}) > #{dice_str} > #{result > 0 ? '成功' : '失敗'}(達成値:#{result})#{has_critical ? ' (クリティカル発生)' : ''}"
59
+ r.critical = has_critical
60
+ r.success = result > 0
61
+ r.failure = !r.success?
62
+ end
56
63
  end
57
64
 
58
65
  TABLES = {
@@ -86,7 +93,7 @@ module BCDice
86
93
  }.freeze
87
94
 
88
95
  # ダイスボットで使用するコマンドを配列で列挙する
89
- register_prefix('\d+AN<=\d([\+\-]\d+)*', TABLES.keys)
96
+ register_prefix('\d+AN<=', TABLES.keys)
90
97
  end
91
98
  end
92
99
  end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Aoharubaan < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'Aoharubaan'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'あおはるばーんっ'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'あおはるはあんつ'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~HELP
17
+ カレカノ反応表( KR, KReaction )
18
+ HELP
19
+
20
+ JUDGE_ROLL_REG = /^(1d6?|d6)(\+\d+)?(>=|=>)(\d+)$/i.freeze
21
+ register_prefix('(1d6?|d6)(\+\d+)?(>=|=>)(\d+)')
22
+
23
+ def eval_game_system_specific_command(command)
24
+ command = ALIAS[command] || command
25
+
26
+ if (m = JUDGE_ROLL_REG.match(command))
27
+ roll_judge(m[2], m[4])
28
+ else
29
+ roll_tables(command, TABLES)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def roll_judge(modifier_expression, border_expression)
36
+ modifier = modifier_expression ? Arithmetic.eval(modifier_expression, RoundType::FLOOR) : nil
37
+ border = border_expression.to_i
38
+
39
+ command_text = make_command_text(modifier, border)
40
+
41
+ dice = @randomizer.roll_once(6)
42
+ score = dice + modifier.to_i
43
+
44
+ is_success = score >= border # 「成功」か?
45
+ is_right = is_success && score == border # 「ピタリ賞」か?
46
+ is_excellent = is_success && score >= 7 # 「限界突破」か?
47
+
48
+ result_elements = []
49
+ result_elements << (is_success ? '成功' : '失敗')
50
+ result_elements << "ピタリ賞" if is_right
51
+ result_elements << "限界突破" if is_excellent
52
+
53
+ message_elements = []
54
+ message_elements << command_text
55
+ message_elements << "#{dice}+#{modifier}" if modifier
56
+ message_elements << score
57
+ message_elements << result_elements.join(" & ")
58
+
59
+ Result.new(message_elements.join(' > ')).tap do |r|
60
+ r.condition = is_success
61
+ r.critical = is_right || is_excellent
62
+ end
63
+ end
64
+
65
+ def make_command_text(modifier, border)
66
+ command = "1D6"
67
+ command = "#{command}+#{modifier}" if modifier
68
+ command = "#{command}>=#{border}"
69
+ "(#{command})"
70
+ end
71
+
72
+ ALIAS = {
73
+ "KR" => "KReaction",
74
+ }.transform_keys(&:upcase).transform_values(&:upcase).freeze
75
+
76
+ TABLES = {
77
+ "KReaction" => DiceTable::RangeTable.new(
78
+ "カレカノ反応表",
79
+ "1D6",
80
+ [
81
+ [1..2, "何となく素っ気ない気がする。"],
82
+ [3..4, "いつもと変わらない安心感。"],
83
+ [5..6, "何故だかすごくデレてきた! 嬉しくて〈テンション〉1回復。"],
84
+ ]
85
+ ),
86
+ }.transform_keys(&:upcase).freeze
87
+
88
+ register_prefix(ALIAS.keys, TABLES.keys)
89
+ end
90
+ end
91
+ end
@@ -25,25 +25,23 @@ module BCDice
25
25
  @d66_sort_type = D66SortType::NO_SORT
26
26
  end
27
27
 
28
- def check_nD6(total, _dice_total, dice_list, cmp_op, target)
28
+ def result_nd6(total, _dice_total, dice_list, cmp_op, target)
29
29
  n_max = dice_list.count(6)
30
30
 
31
31
  if dice_list.count(1) == dice_list.size
32
32
  # 全部1の目ならファンブル
33
- "ファンブル"
33
+ Result.fumble("ファンブル")
34
34
  elsif n_max >= 2
35
35
  # 2個以上6の目があったらクリティカル
36
- "クリティカル(+#{n_max}D6)" if n_max >= 2
36
+ Result.critical("クリティカル(+#{n_max}D6)")
37
37
  elsif cmp_op != :>= || target == '?'
38
- ''
38
+ nil
39
39
  elsif total >= target
40
- "成功"
40
+ Result.success("成功")
41
41
  else
42
- "失敗"
42
+ Result.failure("失敗")
43
43
  end
44
44
  end
45
-
46
- alias check_2D6 check_nD6
47
45
  end
48
46
  end
49
47
  end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class AssaultEngine < Base
6
+ # ゲームシステムの識別子
7
+ ID = 'AssaultEngine'
8
+
9
+ # ゲームシステム名
10
+ NAME = 'アサルトエンジン'
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = 'あさるとえんしん'
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~MESSAGETEXT
17
+ ・判定 AEt (t目標値)
18
+ 例: AE45 (目標値45)
19
+ ・リロール nAEt (nロール前の値、t目標値)
20
+ 例: 76AE45 (目標値45で、76を振り直す)
21
+
22
+ ・スワップ(t目標値) エネミーブックP11
23
+ 例: AES45 (目標値45、スワップ表示あり)
24
+ MESSAGETEXT
25
+
26
+ register_prefix('\d*AE')
27
+
28
+ def initialize(command)
29
+ super(command)
30
+ @round_type = RoundType::FLOOR # 端数切り捨て
31
+ end
32
+
33
+ def eval_game_system_specific_command(command)
34
+ cmd = Command::Parser.new(/AES?/, round_type: round_type).enable_prefix_number
35
+ .has_suffix_number.parse(command)
36
+ return nil unless cmd
37
+
38
+ target = cmd.suffix_number
39
+ target = 99 if target >= 100
40
+
41
+ if cmd.command.include?("AES") # SWAP初回
42
+ total = @randomizer.roll_once(100) % 100 # 0-99
43
+ swap = (total % 10) * 10 + (total / 10)
44
+ r1 = judge(target, total)
45
+ r2 = judge(target, swap)
46
+ text = "(AES#{format00(target)}) > #{r1.text} / スワップ#{r2.text}"
47
+ check_result(r1, r2, text)
48
+ elsif cmd.prefix_number.nil? # 初回ロール
49
+ total = @randomizer.roll_once(100) % 100 # 0-99
50
+ judge(target, total).tap do |r|
51
+ r.text = "(AE#{format00(target)}) > #{r.text}"
52
+ end
53
+ else # リロール
54
+ now = cmd.prefix_number
55
+ die = @randomizer.roll_once(10) % 10 # 0-9
56
+ new1 = judge(target, (now / 10 * 10) + die) # 1の位を振り直す
57
+ new2 = judge(target, now % 10 + die * 10) # 10の位を振り直す
58
+
59
+ text = "(#{format00(now)}AE#{format00(target)}) > #{die} > #{new1.text} / #{new2.text}"
60
+ check_result(new1, new2, text)
61
+ end
62
+ end
63
+
64
+ def format00(dice)
65
+ format("%02d", dice)
66
+ end
67
+
68
+ def check_result(result1, result2, text)
69
+ if result1.critical? || result2.critical?
70
+ Result.critical(text)
71
+ elsif result1.success? || result2.success?
72
+ Result.success(text)
73
+ elsif result1.fumble? && result2.fumble?
74
+ Result.fumble(text)
75
+ else
76
+ Result.failure(text)
77
+ end
78
+ end
79
+
80
+ def judge(target, total)
81
+ double = (total / 10) == (total % 10)
82
+ total_text = format00(total)
83
+ if total <= target
84
+ double ? Result.critical("(#{total_text})クリティカル") : Result.success("(#{total_text})成功")
85
+ else
86
+ double ? Result.fumble("(#{total_text})ファンブル") : Result.failure("(#{total_text})失敗")
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -34,7 +34,7 @@ module BCDice
34
34
  ・8av4*7+10 → 8d10で目標値4、攻撃力7、クリティカルトリガー10の命中判定。
35
35
  MESSAGETEXT
36
36
 
37
- register_prefix('\d+AV\d+((x|\*)\d+(\+\d+)?)?(c\d+)?')
37
+ register_prefix('\d+AV')
38
38
 
39
39
  def initialize(command)
40
40
  super(command)