traveller_rpg 0.0.1.1 → 0.1.0.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.
- checksums.yaml +4 -4
- data/README.md +417 -167
- data/Rakefile +286 -0
- data/VERSION +1 -1
- data/bin/chargen +17 -3
- data/lib/traveller_rpg.rb +31 -169
- data/lib/traveller_rpg/career.rb +242 -201
- data/lib/traveller_rpg/career_path.rb +92 -85
- data/lib/traveller_rpg/careers.rb +256 -544
- data/lib/traveller_rpg/character.rb +114 -123
- data/lib/traveller_rpg/generator.rb +1 -1
- data/lib/traveller_rpg/homeworld.rb +54 -35
- metadata +2 -2
data/lib/traveller_rpg/career.rb
CHANGED
@@ -5,62 +5,35 @@ module TravellerRPG
|
|
5
5
|
class Error < RuntimeError; end
|
6
6
|
class UnknownAssignment < Error; end
|
7
7
|
|
8
|
-
#
|
9
|
-
# Actually useful defaults
|
10
|
-
|
11
8
|
TERM_YEARS = 4
|
12
|
-
ADVANCED_EDUCATION = 8
|
13
9
|
|
14
10
|
#
|
15
|
-
#
|
16
|
-
|
17
|
-
QUALIFICATION = [:default, 5]
|
18
|
-
|
19
|
-
PERSONAL_SKILLS = Array.new(6) { :default }
|
20
|
-
SERVICE_SKILLS = Array.new(6) { :default }
|
21
|
-
ADVANCED_SKILLS = Array.new(6) { :default }
|
11
|
+
# Temporary defaults
|
22
12
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
survival: [:default, 5],
|
28
|
-
advancement: [:default, 5],
|
29
|
-
ranks: RANKS,
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
EVENTS = {
|
34
|
-
2 => nil,
|
35
|
-
3 => nil,
|
36
|
-
4 => nil,
|
37
|
-
5 => nil,
|
38
|
-
6 => nil,
|
39
|
-
7 => nil,
|
40
|
-
8 => nil,
|
41
|
-
9 => nil,
|
42
|
-
10 => nil,
|
43
|
-
11 => nil,
|
44
|
-
12 => nil,
|
13
|
+
EVENTS = Array.new(11) { |i|
|
14
|
+
"Event #{i+2}"
|
15
|
+
}.each.with_index.reduce({}) { |memo, (s,idx)|
|
16
|
+
memo.merge(idx + 2 => { :text => s })
|
45
17
|
}
|
46
|
-
MISHAPS = {
|
47
|
-
1
|
48
|
-
|
49
|
-
|
50
|
-
4 => nil,
|
51
|
-
5 => nil,
|
52
|
-
6 => nil,
|
18
|
+
MISHAPS = Array.new(6) { |i|
|
19
|
+
"Mishap #{i+1}"
|
20
|
+
}.each.with_index.reduce({}) { |memo, (s,idx)|
|
21
|
+
memo.merge(idx + 1 => { :text => s })
|
53
22
|
}
|
54
23
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
24
|
+
#
|
25
|
+
# Needed to function
|
26
|
+
|
27
|
+
# ADVANCED_EDUCATION (false for Drifter)
|
28
|
+
# QUALIFICATION (false for Drifter)
|
29
|
+
# PERSONAL_SKILLS
|
30
|
+
# SERVICE_SKILLS
|
31
|
+
# ADVANCED_SKILLS (unless ADVANCED_EDUCATION is false)
|
32
|
+
# SPECIALIST
|
33
|
+
# EVENTS
|
34
|
+
# MISHAPS
|
35
|
+
# CREDITS
|
36
|
+
# BENEFITS
|
64
37
|
|
65
38
|
def self.roll_check?(label, dm:, check:, roll: nil)
|
66
39
|
roll ||= TravellerRPG.roll('2d6')
|
@@ -69,65 +42,120 @@ module TravellerRPG
|
|
69
42
|
(roll + dm) >= check
|
70
43
|
end
|
71
44
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
45
|
+
# helper method -- handles :choose
|
46
|
+
def self.stat_check(hsh)
|
47
|
+
return hsh if hsh == false
|
48
|
+
raise(Error, hsh.inspect) unless hsh.is_a?(Hash) and hsh.size == 1
|
49
|
+
case hsh[:choose]
|
50
|
+
when Hash
|
51
|
+
s = TravellerRPG.choose("Choose stat check:",
|
52
|
+
*hsh[:choose].keys)
|
53
|
+
[s, hsh[:choose][s]]
|
54
|
+
when NilClass
|
55
|
+
s = hsh.keys.first
|
56
|
+
[s, hsh[s]]
|
57
|
+
else
|
58
|
+
raise(Error, "unexpected choose: #{hsh[:choose]}")
|
59
|
+
end
|
77
60
|
end
|
78
61
|
|
79
|
-
attr_reader :term, :
|
62
|
+
attr_reader :term, :status, :rank, :title, :assignment
|
80
63
|
|
81
|
-
def initialize(char, term: 0,
|
64
|
+
def initialize(char, term: 0, status: :new, rank: 0)
|
82
65
|
@char = char
|
83
66
|
|
84
67
|
# career tracking
|
85
68
|
@term = term
|
86
|
-
@
|
69
|
+
@status = status
|
87
70
|
@rank = rank
|
88
71
|
@term_mandate = nil
|
89
72
|
@title = nil
|
73
|
+
@assignment = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def name
|
77
|
+
self.class.name.split('::').last
|
90
78
|
end
|
91
79
|
|
92
80
|
def officer?
|
93
81
|
false
|
94
82
|
end
|
95
83
|
|
96
|
-
def
|
97
|
-
@
|
84
|
+
def active?
|
85
|
+
@status == :active
|
86
|
+
end
|
87
|
+
|
88
|
+
def finished?
|
89
|
+
[:mishap, :finished].include? @status
|
90
|
+
end
|
91
|
+
|
92
|
+
def must_remain?
|
93
|
+
@term_mandate == :must_remain
|
94
|
+
end
|
95
|
+
|
96
|
+
def must_exit?
|
97
|
+
@term_mandate == :must_exit
|
98
|
+
end
|
99
|
+
|
100
|
+
# move status from :new to :active
|
101
|
+
# take on an assignment
|
102
|
+
# take any rank 0 title or skill
|
103
|
+
#
|
104
|
+
def activate(asg = nil)
|
105
|
+
raise(Error, "can't activate status: #{@status}") unless @status == :new
|
98
106
|
s = self.class::SPECIALIST
|
99
|
-
if
|
100
|
-
raise(UnknownAssignment,
|
101
|
-
@assignment =
|
107
|
+
if asg
|
108
|
+
raise(UnknownAssignment, asg.inspect) unless s.key?(asg)
|
109
|
+
@assignment = asg
|
102
110
|
else
|
103
|
-
@assignment = TravellerRPG.choose("Choose
|
111
|
+
@assignment = TravellerRPG.choose("Choose assignment:", *s.keys)
|
104
112
|
end
|
105
|
-
@
|
106
|
-
|
107
|
-
self
|
113
|
+
@status = :active
|
114
|
+
self.take_rank_benefit
|
108
115
|
end
|
109
116
|
|
110
|
-
def
|
111
|
-
|
117
|
+
def specialty
|
118
|
+
if @assignment and self.class::SPECIALIST.key?(@assignment)
|
119
|
+
self.class::SPECIALIST[@assignment]
|
120
|
+
else
|
121
|
+
raise(Error, "unknown assignment: #{@assignment.inspect}")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def service_skills(choose: false)
|
126
|
+
if choose
|
127
|
+
self.class::SERVICE_SKILLS.map { |s|
|
128
|
+
if s.is_a? Hash
|
129
|
+
TravellerRPG.choose("Choose skill:", *s.fetch(:choose))
|
130
|
+
else
|
131
|
+
s
|
132
|
+
end
|
133
|
+
}
|
134
|
+
else
|
135
|
+
self.class::SERVICE_SKILLS.reduce([]) { |ary, s|
|
136
|
+
ary + (s.is_a?(Hash) ? s.fetch(:choose) : [s])
|
137
|
+
}
|
138
|
+
end
|
112
139
|
end
|
113
140
|
|
114
141
|
def qualify_check?(dm: 0)
|
115
|
-
stat, check = self.class::QUALIFICATION
|
142
|
+
stat, check = self.class.stat_check(self.class::QUALIFICATION)
|
143
|
+
return true if stat == false # only for Drifter
|
116
144
|
@char.log "#{self.name} qualification: #{stat} #{check}+"
|
117
145
|
dm += @char.stats_dm(stat)
|
118
146
|
self.class.roll_check?('Qualify', dm: dm, check: check)
|
119
147
|
end
|
120
148
|
|
121
149
|
def survival_check?(dm: 0)
|
122
|
-
stat, check = self.specialty.fetch(:survival)
|
123
|
-
@char.log "#{self.name} #{@assignment} survival: #{stat} #{check}+"
|
150
|
+
stat, check = self.class.stat_check(self.specialty.fetch(:survival))
|
151
|
+
@char.log "#{self.name} [#{@assignment}] survival: #{stat} #{check}+"
|
124
152
|
dm += @char.stats_dm(stat)
|
125
153
|
self.class.roll_check?('Survival', dm: dm, check: check)
|
126
154
|
end
|
127
155
|
|
128
156
|
def advancement_check?(dm: 0)
|
129
|
-
stat, check = self.specialty.fetch(:advancement)
|
130
|
-
@char.log "#{self.name} #{@assignment} advancement: #{stat} #{check}+"
|
157
|
+
stat, check = self.class.stat_check(self.specialty.fetch(:advancement))
|
158
|
+
@char.log "#{self.name} [#{@assignment}] advancement: #{stat} #{check}+"
|
131
159
|
dm += @char.stats_dm(stat)
|
132
160
|
roll = TravellerRPG.roll('2d6')
|
133
161
|
if roll <= @term
|
@@ -141,91 +169,81 @@ module TravellerRPG
|
|
141
169
|
end
|
142
170
|
|
143
171
|
def advanced_education?
|
144
|
-
|
172
|
+
self.class::ADVANCED_EDUCATION and
|
173
|
+
@char.stats.education >= self.class::ADVANCED_EDUCATION
|
145
174
|
end
|
146
175
|
|
147
|
-
|
176
|
+
def advancement_roll(dm: 0)
|
177
|
+
if self.advancement_check?(dm: dm)
|
178
|
+
self.advance_rank
|
179
|
+
self.training_roll
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# any skills obtained start at level 1; always a bump (+1)
|
148
184
|
def training_roll
|
149
|
-
choices =
|
150
|
-
choices <<
|
151
|
-
choices <<
|
185
|
+
choices = %w{Personal Service Specialist}
|
186
|
+
choices << 'Advanced' if self.advanced_education?
|
187
|
+
choices << 'Officer' if self.officer?
|
152
188
|
choice = TravellerRPG.choose("Choose skills regimen:", *choices)
|
153
|
-
roll = TravellerRPG.roll('d6')
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
189
|
+
roll = TravellerRPG.roll('d6', label: "#{choice} training")
|
190
|
+
skill =
|
191
|
+
case choice
|
192
|
+
when 'Personal' then self.class::PERSONAL_SKILLS.fetch(roll - 1)
|
193
|
+
when 'Service' then self.class::SERVICE_SKILLS.fetch(roll - 1)
|
194
|
+
when 'Specialist' then self.specialty.fetch(:skills).fetch(roll - 1)
|
195
|
+
when 'Advanced' then self.class::ADVANCED_SKILLS.fetch(roll - 1)
|
196
|
+
when 'Officer' then self.class::OFFICER_SKILLS.fetch(roll - 1)
|
197
|
+
end
|
198
|
+
if skill.is_a?(Hash)
|
199
|
+
skill = TravellerRPG.choose("Choose:", *skill.fetch(:choose))
|
200
|
+
end
|
201
|
+
# the "skill" could be a stat e.g. endurance
|
202
|
+
if @char.skills.known?(skill)
|
203
|
+
@char.skills.bump(skill)
|
204
|
+
else
|
205
|
+
@char.stats.bump(skill)
|
206
|
+
end
|
207
|
+
@char.log "Trained #{skill} +1"
|
164
208
|
self
|
165
209
|
end
|
166
210
|
|
167
|
-
def event_roll
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
@char.log "Event: #{self.class::EVENTS.fetch(clamped) || roll}"
|
172
|
-
# TODO: actually perform the event stuff
|
211
|
+
def event_roll
|
212
|
+
ev = self.class::EVENTS.fetch TravellerRPG.roll('2d6', label: 'Event')
|
213
|
+
@char.log "Event: #{ev.fetch(:text)}"
|
214
|
+
# TODO: actually perform the event stuff in ev['script']
|
173
215
|
end
|
174
216
|
|
175
217
|
def mishap_roll
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
# TODO: actually perform the mishap stuff
|
218
|
+
mh = self.class::MISHAPS.fetch TravellerRPG.roll('d6', label: 'Mishap')
|
219
|
+
@char.log "Mishap: #{mh.fetch(:text)}"
|
220
|
+
# TODO: actually perform the mishap stuff in mh['script']
|
180
221
|
end
|
181
222
|
|
182
223
|
def advance_rank
|
183
224
|
@rank += 1
|
184
225
|
@char.log "Advanced career to rank #{@rank}"
|
185
|
-
|
186
|
-
if title
|
187
|
-
@char.log "Awarded rank title: #{title}"
|
188
|
-
@title = title
|
189
|
-
end
|
190
|
-
if skill
|
191
|
-
@char.log "Achieved rank skill: #{skill} #{level}"
|
192
|
-
@char.train(skill, level)
|
193
|
-
end
|
194
|
-
self
|
226
|
+
self.take_rank_benefit
|
195
227
|
end
|
196
228
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
def must_exit?
|
202
|
-
@term_mandate == :must_exit
|
229
|
+
# possibly nil
|
230
|
+
def rank_benefit
|
231
|
+
self.specialty.fetch(:ranks)[@rank]
|
203
232
|
end
|
204
233
|
|
205
234
|
def run_term
|
206
|
-
raise(Error, "career is inactive") unless
|
235
|
+
raise(Error, "career is inactive") unless self.active?
|
207
236
|
raise(Error, "must exit") if self.must_exit?
|
208
237
|
@term += 1
|
209
238
|
@char.log format("%s term %i started, age %i",
|
210
239
|
self.name, @term, @char.age)
|
211
240
|
self.training_roll
|
212
241
|
|
213
|
-
# TODO: DM?
|
214
242
|
if self.survival_check?
|
215
243
|
@char.log format("%s term %i completed successfully.",
|
216
244
|
self.name, @term)
|
217
245
|
@char.age TERM_YEARS
|
218
|
-
|
219
|
-
# TODO: DM?
|
220
|
-
self.commission_roll if self.respond_to?(:commission_roll)
|
221
|
-
|
222
|
-
# TODO: DM?
|
223
|
-
if self.advancement_check?
|
224
|
-
self.advance_rank
|
225
|
-
self.training_roll
|
226
|
-
end
|
227
|
-
|
228
|
-
# TODO: DM?
|
246
|
+
self.advancement_roll # TODO: DM?
|
229
247
|
self.event_roll
|
230
248
|
else
|
231
249
|
years = rand(TERM_YEARS) + 1
|
@@ -233,96 +251,120 @@ module TravellerRPG
|
|
233
251
|
self.name, years)
|
234
252
|
@char.age years
|
235
253
|
self.mishap_roll
|
236
|
-
@
|
254
|
+
@status = :mishap
|
237
255
|
end
|
256
|
+
self
|
238
257
|
end
|
239
258
|
|
240
259
|
def retirement_bonus
|
241
260
|
@term >= 5 ? @term * 2000 : 0
|
242
261
|
end
|
243
262
|
|
244
|
-
|
263
|
+
# returns the roll value with DM applied
|
264
|
+
def muster_roll
|
265
|
+
dm = @char.skills.check?('Gambler', 1) ? 1 : 0
|
266
|
+
TravellerRPG.roll('d6', label: 'Muster', dm: dm)
|
267
|
+
end
|
268
|
+
|
269
|
+
def muster_out
|
245
270
|
@char.log "Muster out: #{self.name}"
|
246
271
|
raise(Error, "career has not started") unless @term > 0
|
247
|
-
dm += @char.skill_check?(:gambler, 1) ? 1 : 0
|
248
|
-
|
249
|
-
# one cash and one benefit per term
|
250
|
-
# except if last term suffered mishap, no benefit for that term
|
251
|
-
|
252
272
|
cash_rolls = @term.clamp(0, 3 - @char.cash_rolls)
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
273
|
+
total_ranks = self.officer? ? self.rank + self.enlisted_rank : self.rank
|
274
|
+
benefit_rolls = @term + ((total_ranks + 1) / 2).clamp(0, 3)
|
275
|
+
|
276
|
+
case @status
|
277
|
+
when :active
|
278
|
+
@char.log "Muster out: Career in good standing; collect all benefits"
|
279
|
+
when :mishap
|
280
|
+
@char.log "Muster out: Career ended early; lose last term benefit"
|
260
281
|
benefit_rolls -= 1
|
282
|
+
when :new, :finished
|
283
|
+
raise "invalid status: #{@status}"
|
284
|
+
else
|
285
|
+
raise "unknown status: #{@status}"
|
261
286
|
end
|
262
287
|
|
288
|
+
# Collect "muster out" benefits
|
263
289
|
cash_rolls.times {
|
264
|
-
|
265
|
-
@char.cash_roll self.class::MUSTER_OUT.fetch(clamped).first
|
290
|
+
@char.cash_roll self.class::CREDITS.fetch(self.muster_roll)
|
266
291
|
}
|
267
292
|
benefit_rolls.times {
|
268
|
-
|
269
|
-
|
293
|
+
b = self.class::BENEFITS.fetch(self.muster_roll)
|
294
|
+
case b
|
295
|
+
when Array
|
296
|
+
b.each { |ben| @char.benefit ben }
|
297
|
+
when Hash
|
298
|
+
choice = TravellerRPG.choose("Choose benefit:", *b.fetch(:choose))
|
299
|
+
@char.benefit choice
|
300
|
+
else
|
301
|
+
@char.benefit b
|
302
|
+
end
|
270
303
|
}
|
271
|
-
@char.log "Retirement bonus: #{self.retirement_bonus}"
|
272
304
|
@char.benefit self.retirement_bonus
|
305
|
+
@status = :finished
|
273
306
|
self
|
274
307
|
end
|
275
308
|
|
276
|
-
def
|
277
|
-
self.class.name.split('::').last
|
278
|
-
end
|
279
|
-
|
280
|
-
def specialty
|
281
|
-
self.class::SPECIALIST.fetch(@assignment)
|
282
|
-
end
|
283
|
-
|
284
|
-
# possibly nil
|
285
|
-
def rank_benefit
|
286
|
-
self.specialty.fetch(:ranks)[@rank]
|
287
|
-
end
|
288
|
-
|
289
|
-
def report(term: true, active: true, rank: true, spec: true)
|
309
|
+
def report(term: true, status: true, rank: true, spec: true)
|
290
310
|
hsh = {}
|
291
311
|
hsh['Term'] = @term if term
|
292
|
-
hsh['
|
312
|
+
hsh['Status'] = @status.to_s.capitalize if status
|
293
313
|
hsh['Specialty'] = @assignment if spec
|
314
|
+
hsh['Title'] = @title if @title
|
294
315
|
if rank
|
295
|
-
|
296
|
-
|
297
|
-
|
316
|
+
if self.officer?
|
317
|
+
hsh['Officer Rank'] = @officer
|
318
|
+
hsh['Enlisted Rank'] = @rank
|
319
|
+
else
|
320
|
+
hsh['Rank'] = @rank
|
321
|
+
end
|
298
322
|
end
|
299
323
|
report = ["Career: #{self.name}", "==="]
|
300
324
|
hsh.each { |label, val|
|
301
|
-
|
302
|
-
report << format("%s: %s", label.to_s.rjust(10, ' '), val.to_s)
|
325
|
+
report << format("%s: %s", label.to_s.rjust(15, ' '), val)
|
303
326
|
}
|
304
327
|
report.join("\n")
|
305
328
|
end
|
306
|
-
end
|
307
329
|
|
330
|
+
protected
|
331
|
+
|
332
|
+
def take_rank_benefit
|
333
|
+
rb = self.rank_benefit or return self
|
334
|
+
label = self.officer? ? "officer rank" : "rank"
|
335
|
+
title, skill, stat, level = rb.values_at(:title, :skill, :stat, :level)
|
336
|
+
if title
|
337
|
+
@char.log "Awarded #{label} title: #{title}"
|
338
|
+
@title = title
|
339
|
+
end
|
340
|
+
if rb[:choose]
|
341
|
+
raise("unexpected choose: #{rb}") unless rb[:choose].is_a?(Array)
|
342
|
+
choices = rb[:choose].map { |h|
|
343
|
+
[h[:skill] || h[:stat], h[:level]].compact.join(' ')
|
344
|
+
}
|
345
|
+
choice = TravellerRPG.choose("Choose rank bonus:", *choices)
|
346
|
+
skill, stat, level = rb[:choose].select { |h|
|
347
|
+
choice == [h[:skill] || h[:stat], h[:level]].compact.join(' ')
|
348
|
+
}.first.values_at(:skill, :stat, :level)
|
349
|
+
raise "#{skill.inspect} or #{stat.inspect}" unless skill or stat
|
350
|
+
end
|
351
|
+
if skill
|
352
|
+
@char.log "Achieved #{label} bonus: #{skill} #{level}"
|
353
|
+
@char.skills.bump(skill, level)
|
354
|
+
end
|
355
|
+
if stat
|
356
|
+
@char.log "Achieved #{label} bonus: #{stat} #{level}"
|
357
|
+
@char.stats.bump(stat, level)
|
358
|
+
end
|
359
|
+
self
|
360
|
+
end
|
361
|
+
end
|
308
362
|
|
309
363
|
#
|
310
|
-
# MilitaryCareer adds Officer commission
|
364
|
+
# MilitaryCareer adds Officer commission opportunity which unlocks
|
365
|
+
# Officer skills and Officer ranks
|
311
366
|
|
312
367
|
class MilitaryCareer < Career
|
313
|
-
|
314
|
-
#
|
315
|
-
# Actually useful defaults
|
316
|
-
|
317
|
-
COMMISSION = [:social_status, 8]
|
318
|
-
|
319
|
-
#
|
320
|
-
# Examples -- but should not be used as actual defaults
|
321
|
-
|
322
|
-
AGE_PENALTY = 40
|
323
|
-
OFFICER_SKILLS = Array.new(6) { :default }
|
324
|
-
OFFICER_RANKS = {}
|
325
|
-
|
326
368
|
def initialize(char, **kwargs)
|
327
369
|
super(char, **kwargs)
|
328
370
|
@officer = false
|
@@ -335,26 +377,33 @@ module TravellerRPG
|
|
335
377
|
end
|
336
378
|
|
337
379
|
def commission_check?(dm: 0)
|
338
|
-
stat, check = self.class::COMMISSION
|
380
|
+
stat, check = self.class.stat_check(self.class::COMMISSION)
|
339
381
|
@char.log "#{self.name} commission: #{stat} #{check}"
|
340
382
|
dm += @char.stats_dm(stat)
|
341
383
|
self.class.roll_check?('Commission', dm: dm, check: check)
|
342
384
|
end
|
343
385
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
if self.commission_check?
|
386
|
+
def advancement_roll(dm: 0)
|
387
|
+
if !@officer and
|
388
|
+
(@term == 1 or @char.stats[:social_status] > 9) and true
|
389
|
+
# TravellerRPG.choose("Apply for commission?", :yes, :no) == :yes
|
390
|
+
comm_dm = @term > 1 ? dm - 1 : dm
|
391
|
+
if self.commission_check?(dm: comm_dm)
|
351
392
|
@char.log "Became an officer!"
|
352
|
-
@officer =
|
353
|
-
self.
|
393
|
+
@officer = 1
|
394
|
+
self.take_rank_benefit
|
395
|
+
|
396
|
+
# skip normal advancement after successful commission
|
397
|
+
# but take the bonus training roll
|
398
|
+
self.training_roll
|
399
|
+
|
400
|
+
return self
|
354
401
|
else
|
355
402
|
@char.log "Commission was rejected"
|
356
403
|
end
|
357
404
|
end
|
405
|
+
# perform normal advancement unless commission was obtained
|
406
|
+
super(dm: dm)
|
358
407
|
end
|
359
408
|
|
360
409
|
#
|
@@ -380,15 +429,7 @@ module TravellerRPG
|
|
380
429
|
return super unless @officer
|
381
430
|
@officer += 1
|
382
431
|
@char.log "Advanced career to officer rank #{@officer}"
|
383
|
-
|
384
|
-
if title
|
385
|
-
@char.log "Awarded officer rank title: #{title}"
|
386
|
-
@title = title
|
387
|
-
end
|
388
|
-
if skill
|
389
|
-
@char.log "Achieved officer rank skill: #{skill} #{level}"
|
390
|
-
@char.train(skill, level)
|
391
|
-
end
|
432
|
+
self.take_rank_benefit
|
392
433
|
end
|
393
434
|
end
|
394
435
|
end
|