bcdice 3.4.0 → 3.5.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -0
  3. data/i18n/BeginningIdol/ja_jp.yml +2806 -0
  4. data/i18n/BeginningIdol/ko_kr.yml +1400 -0
  5. data/i18n/KillDeathBusiness/ja_jp.yml +1 -1
  6. data/i18n/MagicaLogia/ja_jp.yml +1 -1
  7. data/i18n/MonotoneMuseum/ko_kr.yml +526 -53
  8. data/lib/bcdice/common_command/choice.rb +5 -1
  9. data/lib/bcdice/common_command/tally_dice/node.rb +135 -0
  10. data/lib/bcdice/common_command/tally_dice/parser.rb +302 -0
  11. data/lib/bcdice/common_command/tally_dice.rb +19 -0
  12. data/lib/bcdice/common_command.rb +2 -0
  13. data/lib/bcdice/dice_table/d66_table.rb +5 -1
  14. data/lib/bcdice/game_system/Aoharubaan.rb +91 -0
  15. data/lib/bcdice/game_system/AssaultEngine.rb +91 -0
  16. data/lib/bcdice/game_system/BadLife.rb +264 -289
  17. data/lib/bcdice/game_system/Bakenokawa.rb +244 -0
  18. data/lib/bcdice/game_system/BeginningIdol.rb +116 -2390
  19. data/lib/bcdice/game_system/BeginningIdol_Korean.rb +10 -2312
  20. data/lib/bcdice/game_system/CastleInGray.rb +133 -0
  21. data/lib/bcdice/game_system/Cthulhu.rb +2 -2
  22. data/lib/bcdice/game_system/Cthulhu7th.rb +6 -6
  23. data/lib/bcdice/game_system/DoubleCross.rb +5 -0
  24. data/lib/bcdice/game_system/Emoklore.rb +1 -1
  25. data/lib/bcdice/game_system/FateCoreSystem.rb +117 -0
  26. data/lib/bcdice/game_system/Karukami.rb +84 -0
  27. data/lib/bcdice/game_system/KurayamiCrying.rb +1 -1
  28. data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +4 -4
  29. data/lib/bcdice/game_system/{SterileLife.rb → StellarLife.rb} +162 -226
  30. data/lib/bcdice/game_system/SwordWorld.rb +6 -2
  31. data/lib/bcdice/game_system/SwordWorld2_0.rb +20 -5
  32. data/lib/bcdice/game_system/SwordWorld2_5.rb +6 -0
  33. data/lib/bcdice/game_system/TalesFromTheLoop.rb +83 -0
  34. data/lib/bcdice/game_system/YearZeroEngine.rb +40 -19
  35. data/lib/bcdice/game_system/beginning_idol/accessories_table.rb +31 -0
  36. data/lib/bcdice/game_system/beginning_idol/bad_status_table.rb +43 -0
  37. data/lib/bcdice/game_system/beginning_idol/chain_d66_table.rb +29 -0
  38. data/lib/bcdice/game_system/beginning_idol/chain_table.rb +37 -0
  39. data/lib/bcdice/game_system/beginning_idol/costume_table.rb +37 -0
  40. data/lib/bcdice/game_system/beginning_idol/d6_twice_table.rb +36 -0
  41. data/lib/bcdice/game_system/beginning_idol/item_table.rb +51 -0
  42. data/lib/bcdice/game_system/beginning_idol/my_skill_name_table.rb +44 -0
  43. data/lib/bcdice/game_system/beginning_idol/random_event_table.rb +31 -0
  44. data/lib/bcdice/game_system/beginning_idol/skill_table.rb +63 -0
  45. data/lib/bcdice/game_system/beginning_idol/table.rb +193 -0
  46. data/lib/bcdice/game_system/beginning_idol/with_abnormality.rb +74 -0
  47. data/lib/bcdice/game_system/beginning_idol/work_table.rb +57 -0
  48. data/lib/bcdice/game_system/one_way_heroics/random_event_table.rb +4 -4
  49. data/lib/bcdice/game_system/sword_world/rating_parsed.rb +46 -3
  50. data/lib/bcdice/game_system/sword_world/rating_parser.rb +147 -106
  51. data/lib/bcdice/game_system.rb +8 -1
  52. data/lib/bcdice/version.rb +1 -1
  53. metadata +28 -3
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bcdice/game_system/beginning_idol/chain_table"
4
+ require "bcdice/game_system/beginning_idol/chain_d66_table"
5
+ require "bcdice/game_system/beginning_idol/bad_status_table"
6
+ require "bcdice/game_system/beginning_idol/random_event_table"
7
+ require "bcdice/game_system/beginning_idol/my_skill_name_table"
8
+ require "bcdice/game_system/beginning_idol/d6_twice_table"
9
+ require "bcdice/game_system/beginning_idol/item_table"
10
+ require "bcdice/game_system/beginning_idol/costume_table"
11
+ require "bcdice/game_system/beginning_idol/accessories_table"
12
+ require "bcdice/game_system/beginning_idol/with_abnormality"
13
+ require "bcdice/game_system/beginning_idol/work_table"
14
+ require "bcdice/game_system/beginning_idol/skill_table"
15
+
16
+ module BCDice
17
+ module GameSystem
18
+ class BeginningIdol < Base
19
+ class << self
20
+ private
21
+
22
+ def translate_skill_table(locale)
23
+ SkillTable.from_i18n(
24
+ "BeginningIdol.skill_table",
25
+ locale,
26
+ rtt: "AT",
27
+ rttn: ["AT1", "AT2", "AT3", "AT4", "AT5", "AT6"]
28
+ )
29
+ end
30
+
31
+ def translate_tables(locale)
32
+ costume_challenge_girls = CostumeTable.from_i18n("BeginningIdol.tables.DT", locale)
33
+ costume_road_to_prince = CostumeTable.from_i18n("BeginningIdol.tables.RC", locale)
34
+ costume_fortune_stars = CostumeTable.from_i18n("BeginningIdol.tables.FC", locale)
35
+
36
+ bland = ChainTable.new(
37
+ I18n.t("BeginningIdol.ACB.name", locale: locale),
38
+ "1D6",
39
+ [
40
+ [I18n.t("BeginningIdol.ACB.items.challenge_girls", locale: locale), costume_challenge_girls.brand_only()],
41
+ [I18n.t("BeginningIdol.ACB.items.challenge_girls", locale: locale), costume_challenge_girls.brand_only()],
42
+ [I18n.t("BeginningIdol.ACB.items.road_to_prince", locale: locale), costume_road_to_prince.brand_only()],
43
+ [I18n.t("BeginningIdol.ACB.items.road_to_prince", locale: locale), costume_road_to_prince.brand_only()],
44
+ [I18n.t("BeginningIdol.ACB.items.fortune_stars", locale: locale), costume_fortune_stars.brand_only()],
45
+ [I18n.t("BeginningIdol.ACB.items.fortune_stars", locale: locale), costume_fortune_stars.brand_only()],
46
+ ]
47
+ )
48
+
49
+ bad_status_table = BadStatusTable.new(locale)
50
+
51
+ skill_table = translate_skill_table(locale)
52
+
53
+ rare_skill_table = DiceTable::Table.from_i18n("BeginningIdol.rare_skill_table", locale)
54
+
55
+ item_table = ItemTable.new(locale)
56
+
57
+ tn = ChainTable.new(
58
+ I18n.t("BeginningIdol.TN.name", locale: locale),
59
+ "1D6",
60
+ I18n.t("BeginningIdol.TN.items", locale: locale).dup.tap { |items| items[3].push(skill_table) }
61
+ )
62
+
63
+ cg = ChainTable.new(
64
+ I18n.t("BeginningIdol.CG.name", locale: locale),
65
+ "1D6",
66
+ I18n.t("BeginningIdol.CG.items", locale: locale).map.with_index do |item, index|
67
+ if [3, 4].include?(index)
68
+ [item, item_table]
69
+ else
70
+ [item]
71
+ end
72
+ end
73
+ )
74
+
75
+ gg = ChainD66Table.new(
76
+ I18n.t("BeginningIdol.GG.name", locale: locale),
77
+ I18n.t("BeginningIdol.GG.items", locale: locale).to_h do |index, value|
78
+ chain =
79
+ if [23, 24, 25].include?(index)
80
+ [value, rare_skill_table]
81
+ elsif index == 56
82
+ [value, item_table]
83
+ else
84
+ [value]
85
+ end
86
+
87
+ [index, chain]
88
+ end
89
+ )
90
+
91
+ ha = ChainD66Table.new(
92
+ I18n.t("BeginningIdol.HA.name", locale: locale),
93
+ I18n.t("BeginningIdol.HA.items", locale: locale).dup.tap { |items| items[22].push(SkillHometown.new(skill_table)) }
94
+ )
95
+
96
+ {
97
+ "DT" => costume_challenge_girls,
98
+ "RC" => costume_road_to_prince,
99
+ "FC" => costume_fortune_stars,
100
+ "ACB" => bland,
101
+ "TN" => tn,
102
+ "CG" => cg,
103
+ "GG" => gg,
104
+ "HA" => ha,
105
+ "CBT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.CBT", locale),
106
+ "RCB" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.RCB", locale),
107
+ "HBT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.HBT", locale),
108
+ "RHB" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.RHB", locale),
109
+ "RU" => DiceTable::Table.from_i18n("BeginningIdol.tables.RU", locale),
110
+ "SIP" => DiceTable::Table.from_i18n("BeginningIdol.tables.SIP", locale),
111
+ "BU" => DiceTable::Table.from_i18n("BeginningIdol.tables.BU", locale),
112
+ "HW" => DiceTable::Table.from_i18n("BeginningIdol.tables.HW", locale),
113
+ "FL" => DiceTable::Table.from_i18n("BeginningIdol.tables.FL", locale),
114
+ "MSE" => DiceTable::Table.from_i18n("BeginningIdol.tables.MSE", locale),
115
+ "ST" => DiceTable::Table.from_i18n("BeginningIdol.tables.ST", locale),
116
+ "FST" => DiceTable::Table.from_i18n("BeginningIdol.tables.FST", locale),
117
+ "BWT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.BWT", locale),
118
+ "LWT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.LWT", locale),
119
+ "TWT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.TWT", locale),
120
+ "CWT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.CWT", locale),
121
+ "SU" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.SU", locale),
122
+ "WI" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.WI", locale),
123
+ "NA" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.NA", locale),
124
+ "GA" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.GA", locale),
125
+ "BA" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.BA", locale),
126
+ "WT" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.WT", locale),
127
+ "VA" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.VA", locale),
128
+ "MU" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.MU", locale),
129
+ "DR" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.DR", locale),
130
+ "VI" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.VI", locale),
131
+ "SP" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.SP", locale),
132
+ "CHR" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.CHR", locale),
133
+ "PAR" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.PAR", locale),
134
+ "SW" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.SW", locale),
135
+ "AN" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.AN", locale),
136
+ "MOV" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.MOV", locale),
137
+ "FA" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.FA", locale),
138
+ "BVT" => DiceTable::Table.from_i18n("BeginningIdol.tables.BVT", locale),
139
+ "LVT" => DiceTable::Table.from_i18n("BeginningIdol.tables.LVT", locale),
140
+ "TVT" => DiceTable::Table.from_i18n("BeginningIdol.tables.TVT", locale),
141
+ "CVT" => DiceTable::Table.from_i18n("BeginningIdol.tables.CVT", locale),
142
+ "BST" => DiceTable::Table.from_i18n("BeginningIdol.tables.BST", locale),
143
+ "LST" => DiceTable::Table.from_i18n("BeginningIdol.tables.LST", locale),
144
+ "TST" => DiceTable::Table.from_i18n("BeginningIdol.tables.TST", locale),
145
+ "CST" => DiceTable::Table.from_i18n("BeginningIdol.tables.CST", locale),
146
+ "BPT" => DiceTable::Table.from_i18n("BeginningIdol.tables.BPT", locale),
147
+ "LPT" => DiceTable::Table.from_i18n("BeginningIdol.tables.LPT", locale),
148
+ "TPT" => DiceTable::Table.from_i18n("BeginningIdol.tables.TPT", locale),
149
+ "CPT" => DiceTable::Table.from_i18n("BeginningIdol.tables.CPT", locale),
150
+ "BIT" => DiceTable::Table.from_i18n("BeginningIdol.tables.BIT", locale),
151
+ "LIT" => DiceTable::Table.from_i18n("BeginningIdol.tables.LIT", locale),
152
+ "TIT" => DiceTable::Table.from_i18n("BeginningIdol.tables.TIT", locale),
153
+ "CIT" => DiceTable::Table.from_i18n("BeginningIdol.tables.CIT", locale),
154
+ "CHO" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.CHO", locale),
155
+ "SCH" => DiceTable::Table.from_i18n("BeginningIdol.tables.SCH", locale),
156
+ "WCH" => DiceTable::Table.from_i18n("BeginningIdol.tables.WCH", locale),
157
+ "NCH" => DiceTable::Table.from_i18n("BeginningIdol.tables.NCH", locale),
158
+ "GCH" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.GCH", locale),
159
+ "PCH" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.PCH", locale),
160
+ "LUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.LUR", locale),
161
+ "SUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.SUR", locale),
162
+ "WUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.WUR", locale),
163
+ "NUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.NUR", locale),
164
+ "GUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.GUR", locale),
165
+ "BUR" => D6TwiceTable.from_i18n("BeginningIdol.tables.BUR", locale),
166
+ "ACE" => DiceTable::D66Table.from_i18n("BeginningIdol.tables.ACE", locale),
167
+ "ACT" => translate_accessories_table(locale),
168
+ "MS" => MySkillNameTable.new(locale),
169
+ "RE" => RandomEventTable.new(locale),
170
+ "SH" => D66WithAbnormality.from_i18n("BeginningIdol.tables.SH", bad_status_table, locale),
171
+ "MO" => D66WithAbnormality.from_i18n("BeginningIdol.tables.MO", bad_status_table, locale),
172
+ "SEA" => D66WithAbnormality.from_i18n("BeginningIdol.tables.SEA", bad_status_table, locale),
173
+ "SPA" => D66WithAbnormality.from_i18n("BeginningIdol.tables.SPA", bad_status_table, locale),
174
+ "LN" => TableWithAbnormality.from_i18n("BeginningIdol.tables.LN", bad_status_table, locale),
175
+ "SGT" => SkillGetTable.from_i18n("BeginningIdol.tables.SGT", skill_table, locale),
176
+ "RS" => SkillGetTable.from_i18n("BeginningIdol.tables.RS", skill_table, locale),
177
+ }
178
+ end
179
+ end
180
+
181
+ TABLES = translate_tables(:ja_jp)
182
+
183
+ BAD_STATUS_TABLE = BadStatusTable.new(:ja_jp)
184
+
185
+ LOCAL_WORK_TABLE = translate_local_work_table(:ja_jp)
186
+ ITEM_TABLE = ItemTable.new(:ja_jp)
187
+
188
+ SKILL_TABLE = translate_skill_table(:ja_jp)
189
+
190
+ register_prefix(TABLES.keys)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class BeginningIdol < Base
6
+ module WithAbnormality
7
+ def replace_abnormality(chosen, randomizer)
8
+ reg = Regexp.new(I18n.t("BeginningIdol.abnormality.regexp", locale: @locale))
9
+ m = reg.match(chosen.body)
10
+ unless m
11
+ return chosen
12
+ end
13
+
14
+ abno_count = kanji_to_i(m[1])
15
+ unless abno_count
16
+ return chosen
17
+ end
18
+
19
+ text = @bad_status_table.roll(randomizer, abno_count)
20
+ new_body = chosen.body.sub(reg, text)
21
+
22
+ return DiceTable::RollResult.new(chosen.table_name, chosen.value, new_body)
23
+ end
24
+
25
+ def kanji_to_i(kanji)
26
+ list = I18n.t("BeginningIdol.abnormality.num_map", locale: @locale)
27
+ list.find_index(kanji)&.succ
28
+ end
29
+ end
30
+
31
+ class D66WithAbnormality < DiceTable::D66Table
32
+ include WithAbnormality
33
+
34
+ def self.from_i18n(key, bad_status_table, locale)
35
+ table = I18n.t(key, locale: locale)
36
+ sort_type = D66SortType.const_get(table[:d66_sort_type])
37
+
38
+ new(table[:name], sort_type, table[:items], bad_status_table, locale)
39
+ end
40
+
41
+ def initialize(name, sort_type, items, bad_status_table, locale)
42
+ super(name, sort_type, items)
43
+ @bad_status_table = bad_status_table
44
+ @locale = locale
45
+ end
46
+
47
+ def roll(randomizer)
48
+ chosen = super(randomizer)
49
+ replace_abnormality(chosen, randomizer)
50
+ end
51
+ end
52
+
53
+ class TableWithAbnormality < DiceTable::Table
54
+ include WithAbnormality
55
+
56
+ def self.from_i18n(key, bad_status_table, locale)
57
+ table = I18n.t(key, locale: locale)
58
+ new(table[:name], table[:type], table[:items], bad_status_table, locale)
59
+ end
60
+
61
+ def initialize(name, type, items, bad_status_table, locale)
62
+ super(name, type, items)
63
+ @bad_status_table = bad_status_table
64
+ @locale = locale
65
+ end
66
+
67
+ def roll(randomizer)
68
+ chosen = super(randomizer)
69
+ replace_abnormality(chosen, randomizer)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class BeginningIdol < Base
6
+ class WorkWithChanceTable < DiceTable::D66Table
7
+ def self.from_i18n(key, locale)
8
+ table = I18n.t(key, locale: locale)
9
+ sort_type = D66SortType.const_get(table[:d66_sort_type])
10
+
11
+ new(table[:name], sort_type, table[:items], locale)
12
+ end
13
+
14
+ def initialize(name, sort_type, items, locale)
15
+ super(name, sort_type, items)
16
+ @regexp = Regexp.new(I18n.t("BeginningIdol.with_chance.regexp", locale: locale))
17
+ @off = I18n.t("BeginningIdol.with_chance.off_text", locale: locale)
18
+ end
19
+
20
+ def roll_command(randomizer, command)
21
+ m = /^LO([1-6]{1,2})?$/.match(command)
22
+ unless m
23
+ return nil
24
+ end
25
+
26
+ roll(randomizer, m[1]&.to_i)
27
+ end
28
+
29
+ def roll(randomizer, chance = nil)
30
+ chosen = super(randomizer)
31
+ unless chance
32
+ return chosen
33
+ end
34
+
35
+ m = @regexp.match(chosen.body)
36
+ if m && m[1].to_i >= chance
37
+ DiceTable::RollResult.new(chosen.table_name, chosen.value, @off)
38
+ elsif m
39
+ DiceTable::RollResult.new(chosen.table_name, chosen.value, chosen.body.sub(@regexp, ""))
40
+ else
41
+ chosen
42
+ end
43
+ end
44
+ end
45
+
46
+ class << self
47
+ private
48
+
49
+ def translate_local_work_table(locale)
50
+ WorkWithChanceTable.from_i18n("BeginningIdol.local_work", locale)
51
+ end
52
+ end
53
+
54
+ register_prefix("LO")
55
+ end
56
+ end
57
+ end
@@ -44,7 +44,7 @@ module BCDice
44
44
 
45
45
  def roll_with_day(day, randomizer)
46
46
  value = randomizer.roll_once(6)
47
- chosen = choise(value, day)
47
+ chosen = choice(value, day)
48
48
 
49
49
  chosen =
50
50
  if chosen.respond_to?(:roll_with_day)
@@ -63,7 +63,7 @@ module BCDice
63
63
  return result
64
64
  end
65
65
 
66
- def choise(value, day)
66
+ def choice(value, day)
67
67
  raise NotImplementedError
68
68
  end
69
69
 
@@ -73,7 +73,7 @@ module BCDice
73
73
  end
74
74
 
75
75
  class BranchByElapsedDays < BranchByDay
76
- def choise(value, day)
76
+ def choice(value, day)
77
77
  value > day ? @greater : @less_than_equal
78
78
  end
79
79
 
@@ -87,7 +87,7 @@ module BCDice
87
87
  end
88
88
 
89
89
  class BranchByDayParity < BranchByDay
90
- def choise(value, _)
90
+ def choice(value, _)
91
91
  value.odd? ? @greater : @less_than_equal
92
92
  end
93
93
 
@@ -25,6 +25,12 @@ module BCDice
25
25
  # @return [Boolean]
26
26
  attr_accessor :greatest_fortune
27
27
 
28
+ # @return [Integer, nil]
29
+ attr_writer :semi_fixed_val
30
+
31
+ # @return [Integer, nil]
32
+ attr_writer :tmp_fixed_val
33
+
28
34
  # @return [Integer]
29
35
  attr_accessor :modifier
30
36
 
@@ -33,11 +39,14 @@ module BCDice
33
39
 
34
40
  def initialize
35
41
  @critical = nil
42
+ @min_critical = nil
36
43
  @kept_modify = nil
37
44
  @first_to = nil
38
45
  @first_modify = nil
39
46
  @greatest_fortune = false
40
47
  @rateup = nil
48
+ @semi_fixed_val = nil
49
+ @tmp_fixed_val = nil
41
50
  end
42
51
 
43
52
  # @return [Boolean]
@@ -47,9 +56,22 @@ module BCDice
47
56
 
48
57
  # @return [Integer]
49
58
  def critical
50
- crit = @critical || (half ? 13 : 10)
51
- crit = 3 if crit < 3
52
- return crit
59
+ return @critical || (half ? 13 : 10)
60
+ end
61
+
62
+ # @return [Integer]
63
+ def min_critical
64
+ min_critical = 3
65
+ unless @semi_fixed_val.nil?
66
+ if @kept_modify.nil?
67
+ min_critical = @semi_fixed_val + 2 if min_critical < @semi_fixed_val + 2
68
+ else
69
+ min_critical = @semi_fixed_val + @kept_modify + 2 if min_critical < @semi_fixed_val + @kept_modify + 2
70
+ end
71
+ min_critical = 3 if @semi_fixed_val == 1
72
+ end
73
+ min_critical = 13 if min_critical > 13
74
+ return min_critical
53
75
  end
54
76
 
55
77
  # @return [Integer]
@@ -67,6 +89,20 @@ module BCDice
67
89
  return @rateup || 0
68
90
  end
69
91
 
92
+ # @return [Integer]
93
+ def semi_fixed_val
94
+ sf = @semi_fixed_val || 0
95
+ sf = 6 if sf > 6
96
+ return sf
97
+ end
98
+
99
+ # @return [Integer]
100
+ def tmp_fixed_val
101
+ tf = @tmp_fixed_val || 0
102
+ tf = 6 if tf > 6
103
+ return tf
104
+ end
105
+
70
106
  # @return [Integer]
71
107
  def kept_modify
72
108
  return @kept_modify || 0
@@ -86,6 +122,8 @@ module BCDice
86
122
  output += "m[#{first_to}]" if first_to != 0
87
123
  output += "r[#{rateup}]" if rateup != 0
88
124
  output += "gf" if @greatest_fortune
125
+ output += "sf[#{semi_fixed_val}]" if semi_fixed_val != 0
126
+ output += "tf[#{tmp_fixed_val}]" if tmp_fixed_val != 0
89
127
  output += "a[#{Format.modifier(kept_modify)}]" if kept_modify != 0
90
128
 
91
129
  if @modifier != 0
@@ -93,6 +131,11 @@ module BCDice
93
131
  end
94
132
  return output
95
133
  end
134
+
135
+ # @return [Boolean]
136
+ def infinite_roll?
137
+ return critical < min_critical
138
+ end
96
139
  end
97
140
  end
98
141
  end