-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdm_assistant.rb
More file actions
192 lines (160 loc) · 4.82 KB
/
dm_assistant.rb
File metadata and controls
192 lines (160 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
require 'rubygems'
require 'bundler/setup'
require 'pry'
require 'tty-prompt'
Dir['./lib/**/*.rb'].each { |f| require f }
class Runner
ENCOUNTER_TYPES = { 'Urban' => Urban, 'Wilderness' => Wilderness, 'Undersea' => Undersea }.freeze
BUILDING_TYPES = { 'Tavern' => Tavern, 'Warehouse' => Warehouse }.freeze
def initialize
@campaign = nil
@prompt = TTY::Prompt.new
end
def run
until (choice = main_menu) == 'Quit'
handle(choice)
end
end
private
def divider
puts "\n* * * * * * * * * * * *\n"
end
def main_menu
header = @campaign ? "Campaign: #{@campaign.name}\n\n" : ''
items = ['Name', 'Encounters', 'Settlement', 'Buildings']
items += @campaign ? ['Campaign'] : ['New Campaign', 'Load Campaign']
items << 'Quit'
@prompt.select("#{header}Choose your destiny?", items, per_page: 12)
end
def handle(choice)
divider
case choice
when 'Encounters' then handle_encounters
when 'Settlement' then handle_settlement_menu
when 'Buildings' then handle_buildings
when 'Name' then puts NameGenerator.new
when 'Campaign' then handle_campaign_menu
when 'New Campaign' then new_campaign
when 'Load Campaign' then load_campaign
end
divider
end
# --- Encounters ---
def handle_encounters
choice = @prompt.select('Encounter type?', ENCOUNTER_TYPES.keys + ['Back'])
return if choice == 'Back'
encounter = ENCOUNTER_TYPES[choice].new
puts encounter
offer_add_to_campaign(encounter, :add_encounter)
end
# --- Settlements ---
def handle_settlement_menu
choice = @prompt.select('Settlement?', ['New Settlement', 'Load Settlement', 'Back'])
case choice
when 'New Settlement' then handle_new_settlement
when 'Load Settlement' then handle_load_settlement
end
end
def handle_new_settlement
settlement = Settlement.new
puts settlement.to_table
if @campaign
offer_add_to_campaign(settlement, :add_settlement)
else
settlement.save
end
end
def handle_load_settlement
if @campaign
load_settlement_from_campaign
else
load_settlement_from_disk
end
end
def load_settlement_from_campaign
settlements = @campaign.settlements
if settlements.empty?
puts 'No settlements in this campaign.'
return
end
settlement = @prompt.select('Choose a settlement') do |menu|
settlements.each { |s| menu.choice s.name.to_s, s }
end
puts settlement.to_table
end
def load_settlement_from_disk
files = Dir['./userdata/settlement-*.yml']
if files.empty?
puts 'No saved settlements found.'
return
end
filename = @prompt.select('Choose a settlement') do |menu|
files.each { |f| menu.choice File.basename(f, '.yml').sub('settlement-', ''), f }
end
puts Settlement.load(filename).to_table
end
# --- Buildings ---
def handle_buildings
choice = @prompt.select('Building type?', BUILDING_TYPES.keys + ['Back'])
return if choice == 'Back'
building = BUILDING_TYPES[choice].new
puts building
offer_add_to_campaign(building, :add_building)
end
# --- Campaign ---
def handle_campaign_menu
choice = @prompt.select("Campaign: #{@campaign.name}", [
'View Settlements', 'View Encounters', 'View Buildings', 'Save', 'Close', 'Back'
])
case choice
when 'View Settlements' then view_collection(@campaign.settlements, 'Settlements')
when 'View Encounters' then view_collection(@campaign.encounters, 'Encounters')
when 'View Buildings' then view_collection(@campaign.buildings, 'Buildings')
when 'Save' then save_campaign
when 'Close' then close_campaign
end
end
def view_collection(items, label)
if items.empty?
puts "No #{label.downcase} in this campaign."
else
puts "#{label}:"
items.each { |item| puts " - #{item}" }
end
end
def new_campaign
name = @prompt.ask('Campaign name?')
@campaign = Campaign.new(name: name)
puts "Campaign '#{name}' created."
end
def load_campaign
files = Dir['./userdata/campaign-*.yml']
if files.empty?
puts 'No saved campaigns found.'
return
end
filename = @prompt.select('Choose a campaign') do |menu|
files.each { |f| menu.choice File.basename(f, '.yml').sub('campaign-', ''), f }
end
@campaign = Campaign.load(filename)
puts "Campaign '#{@campaign.name}' loaded."
end
def save_campaign
@campaign.save
puts "Campaign '#{@campaign.name}' saved."
end
def close_campaign
save_campaign
@campaign = nil
puts 'Campaign closed.'
end
# --- Helpers ---
def offer_add_to_campaign(item, method)
return unless @campaign
if @prompt.yes?("Add to campaign '#{@campaign.name}'?")
@campaign.send(method, item)
save_campaign
end
end
end
Runner.new.run