-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathamar.rb
executable file
·280 lines (248 loc) · 9.97 KB
/
amar.rb
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#! /usr/bin/ruby
#encoding: utf-8
# Welcome to Amar Tools (https://github.com/isene/Amar-Tools)
#
# This file is the umbrella for Amar Tools to work as CLI/terminal program.
@help = <<HELP
Notes on the usage of NPC Generation for the Amar RPG
This program will only make sense to you if you know what role-playing games (RPGs) are. It is a useful asset to the Amar RPG.
The program is used for creating villages/towns/cities, random or specific encounters (basic details) or detailed NPC generation as well
as random weather for a month. It can also generate relationship maps for inhabitants of a town or for a list of NPCs (with a graphical
map showing the various positive and negative relations between them.
There is also an Open Ended Dice roller for the Amar RPG (see the rules for what that is and how it is used in the game). That program is
written in the nim programming language and compiled as a stand-alone executable called "O6". Simply put this in your path and you can
throw an Open Ended Dice roll simply by running O6 on the command line..
You may select or enter values in any of the NPC's characteristics. Those you don't will be randomly generated. When you have selected/
entered the values you want, press "submit", and the NPC will be generated.
When generating a town relationship map, you can upload a file with the same format as the one generated when creating a random town. The
map will then have the name, basic info and the house number in an ellipse for each person that has a special relationship with others in
the town. Or you can simply upload a list of characters, one per line and every line with a special relationship will be paired with
other lines in the file. A black line indicates a special positive relation, while a red line signifies a special negative relation. A
double black line shows a strong alliance, while a double red shows deep hate. A black and a red line indicates a complex relationship. A
graphical map is created as a .png file in the npcg directory.
Press "v" when a town, encounters or an NPC is presented to edit the values in your default editor. The files for a detailed NPC
(temp.npc), random encounter (encounter.npc), random town (town.npc) or random weather (weather.npc) is generated in the "npcs" directory
under "npcg".
Happy generation :)
Several abbreviations are used. They are easily deciphered if you read the Amar RPG rules.
The more obscure ones are: Spell Heading: A?=Active/Passive? Here a "+" means both Active and passive. R?=Resist? AoE="Area Of Effect",
and we have A=Animal, C=Creature, D=Demon, E=Elemental, O=Object, S=Spell, U=Undead, W=Weapon.
The asterisk indicates that it will increase with the spell level. 1mr = 1 meter radius.
This program is licensed under the Gnu General Public License, Copyright 2002-2015, Geir Isene.
HELP
# Require the various modules needed
require 'date'
begin
require 'optparse'
rescue
puts "Ruby module 'optparse' is required. Please install: gem install optparse"
exit
end
begin
require 'tty-prompt'
rescue
puts "Ruby module 'tty-prompt' is required. Please install: gem install tty-prompt"
exit
end
$dark = true
# Handle options
options = {}
optparse = OptionParser.new do |opts|
# Set a banner, displayed at the top of the help screen.
opts.banner = "Usage: amar.rb [options]"
# Define the options, and what they do
opts.on('-e', 'Set Editor to use (default = less') { |e| $editor = e }
opts.on('-l', 'Use theme for terminals with light background') { $dark = false }
opts.on('-h', 'Display SHORT help text') { puts opts; exit }
opts.on('--help', 'Display LONG help text') { puts @help; exit }
opts.on('-v', '--version', 'Amar Tools version number') { puts "Version = 1.2\n"; exit }
end
optparse.parse!
$editor = "less" if $editor == "" or $editor == nil
# Extend String Class to use colors
class String
# colorization
def c(code)
"\e[38;5;#{code}m#{self}\e[0m"
end
def cb(code)
"\e[38;5;#{code};1m#{self}\e[0m"
end
def ci(code)
"\e[38;5;#{code};3m#{self}\e[0m"
end
def cu(code)
"\e[38;5;#{code};4m#{self}\e[0m"
end
end
# Define colors
$dark ? @A = 194 : @A = 29
$dark ? @I = 194 : @I = 29
$dark ? @e = 231 : @e = 65
$dark ? @E = 230 : @E = 64
$dark ? @n = 229 : @n = 29
$dark ? @N = 228 : @N = 28
$dark ? @t = 223 : @t = 59
$dark ? @r = 222 : @r = 58
$dark ? @m = 228 : @m = 94
$dark ? @w = 225 : @w = 57
@red = 160
@gray = 240
prompt = TTY::Prompt.new
# Define a function to get OpenAI response
def openai(type)
p = TTY::Prompt.new
if type == "adv"
cmd = "openai -f " + __dir__ + "/adv.txt -x 1800"
elsif type == "gen"
req = p.ask("\nEnter a request for OpenAI:").to_s
text = File.read(__dir__ + "/gen.txt") + req
cmd = "openai -t \"#{text}\" -x 2000"
elsif type == "npc"
fl = "temp.npc"
f = p.ask("\nEnter npc file name (default is the latest generated [temp.npc]):").to_s
fl = f unless f == ""
fl = __dir__ + "/saved/" + fl
text = File.read(__dir__ + "/npc.txt")
cmd = "openai -t \"#{text}\" -f " + fl + " -x 2000"
elsif type == "enc"
fl = "encounter.npc"
f = p.ask("\nEnter encounter file name (default is the latest generated [encounter.npc]):").to_s
fl = f unless f == ""
fl = __dir__ + "/saved/" + fl
text = File.read(__dir__ + "/enc.txt")
cmd = "openai -t \"#{text}\" -f " + fl + " -x 2000"
end
puts "\nGetting response from OpenAI... (quality may vary, use at your own discretion)\n".c(@gray)
begin
puts 'OpenAI response is written to the file "openai.txt" in the directory "saved".'
resp = %x[#{cmd}]
twidth = `tput cols`.to_i
puts resp.gsub(/(.{1,#{twidth}})( +|$\n?)|(.{1,#{twidth}})/, "\\1\\3\n")
File.write("saved/openai.txt", resp, perm: 0644)
rescue => error
p error
puts "\nYou need to install openai-term to use this feature (see https://github.com/isene/openai)"
end
p.keypress("\nPress any key...".c(@gray))
end
# Deal with the directory from which NPCg is run then the arguments
if File::symlink?($0)
$pgmdir = File::dirname(File::expand_path(File::readlink($0), \
File::dirname(File::expand_path($0))))
else
$pgmdir = File::dirname(File::expand_path($0))
end
Dir.chdir($pgmdir)
# Include all core files via includes.rb
load "includes/includes.rb"
# Include all CLI modules
load "cli_npc_input.rb"
load "cli_npc_output.rb"
load "cli_enc_input.rb"
load "cli_enc_output.rb"
load "cli_town_input.rb"
load "cli_town_output.rb"
load "cli_name_gen.rb"
load "cli_weather_input.rb"
load "cli_weather_output.rb"
# Set initial global encounter default values
$Day = 1
$Terrain = 0
$Terraintype = 8
$Level = 0
# Data enters via an input module, is initialized and rendered by an output module.
loop do
system "clear"
puts "\nTools for the Amar RPG. Press a key to access the desired tool:\n\n"
puts "A".cb(@A) + " = Generate an adventure from OpenAI".c(@A)
puts "I".cb(@I) + " = Make a general question or request to OpenAI".c(@I)
puts "e".cb(@e) + " = Random encounter".c(@e)
puts "E".cb(@E) + " = Generate a description for a random encounter (via OpenAI)".c(@E)
puts "n".cb(@n) + " = Generate a detailed human NPC".c(@n)
puts "N".cb(@N) + " = Generate a description for an NPC (via OpenAI)".c(@N)
puts "t".cb(@t) + " = Create a village/town/city".c(@t)
puts "r".cb(@r) + " = Make town relations".c(@r)
puts "m".cb(@m) + " = Generate names".c(@m)
puts "w".cb(@w) + " = Generate a month of weather".c(@w)
puts "q".cb(@gray) + " = Quit npcg\n".c(@gray)
c = prompt.keypress()
# q = Quit
if c == "q"
puts ""
break
# A = Generate an adventure
elsif c == "A"
openai("adv")
# I = Generate an adventure
elsif c == "I"
openai("gen")
# e = Random Encounter
elsif c == "e"
ia = enc_input
loop do
anENC = Enc.new(ia[0], ia[1])
enc_output(anENC, "cli")
puts "\n\nPress the ENTER key if you want to re-roll with the same inputs. All other keys bring up the main menu."
break if STDIN.getch != "\r"
end
# E = Generate Encounter description
elsif c == "E"
openai("enc")
# n = Random NPC
elsif c == "n"
# Reload chartypes as it gets reworked every time
ia = npc_input
loop do
load "includes/tables/chartype.rb"
aNPC = Npc.new(ia[0], ia[1], ia[2], ia[3], ia[4], ia[5], ia[6], ia[7], ia[8])
npc_output(aNPC, "cli")
puts "\n\nPress the ENTER key if you want to re-roll with the same inputs. All other keys bring up the main menu."
break if STDIN.getch != "\r"
end
# N = Generate NPC description
elsif c == "N"
openai("npc")
# t = Random Town (castle/village/town/city)
elsif c == "t"
ia = town_input
loop do
aTOWN = Town.new(ia[0], ia[1], ia[2])
town_output(aTOWN, "cli")
puts "\n\nPress the ENTER key if you want to re-roll with the same inputs. All other keys bring up the main menu."
break if STDIN.getch != "\r"
end
# r = Random relationship map
elsif c == "r"
town_file = __dir__ + "saved/town.npc"
#Get town file name
fl = prompt.ask("\nEnter town file name (default is the latest town generated [town.npc]):".c(@r))
town_file = __dir__ + "/saved/" + fl unless fl == ""
town_relations(town_file)
town_dot2txt(town_file)
prompt.keypress("\nPress any key...".c(@gray))
# m = Random names
elsif c == "m"
name_gen
prompt.keypress("\nPress any key...".c(@gray))
# w = Random weather
elsif c == "w"
$weather_n = 1 if $weather_n == nil
$wind_dir_n = 0 if $wind_dir_n == nil
$wind_str_n = 0 if $wind_str_n == nil
$mn = 0 if $mn == nil
if $mn != 0
$mn = (($mn + 1) % 14)
$mn = 1 if $mn == 0
end
ia = weather_input
$mn = ia[0]
w = Weather_month.new(ia[0], ia[1], ia[2])
$weather_n = w.day[27].weather
$wind_dir_n = w.day[27].wind_dir
$wind_str_n = w.day[27].wind_str
weather_output(w)
weather_out_latex(w,"cli")
end
end
# And that's all folks. G'day.