class Gemwarrior::Repl
Constants
- ERROR_SOUND_NOT_ENABLED
- GITHUB_NAME
- GITHUB_PROJECT
- MAIN_MENU_QUIT_MESSAGE
- QUIT_MESSAGE
- SCREEN_WIDTH_MAX
- SCREEN_WIDTH_MIN
CONSTANTS
- SPLASH_MESSAGE
Attributes
evaluator[RW]
game[RW]
world[RW]
Public Class Methods
new(game, world, evaluator)
click to toggle source
# File lib/gemwarrior/repl.rb, line 32 def initialize(game, world, evaluator) self.game = game self.world = world self.evaluator = evaluator GameOptions.data['wrap_width'] = get_screen_width end
Public Instance Methods
get_screen_width()
click to toggle source
# File lib/gemwarrior/repl.rb, line 40 def get_screen_width screen_width = SCREEN_WIDTH_MIN begin require 'io/console' screen_width = IO.console.winsize[1] rescue if command_exists?('tput') screen_width = `tput cols`.to_i elsif command_exists?('stty') screen_width = `stty size`.split.last.to_i elsif command_exists?('mode') mode_output = `mode`.split screen_width = mode_output[mode_output.index('Columns:')+1].to_i end end case when screen_width.nil?, screen_width <= 0 return SCREEN_WIDTH_MIN else return [screen_width, SCREEN_WIDTH_MAX].min end end
main_loop(ext_input = nil)
click to toggle source
# File lib/gemwarrior/repl.rb, line 92 def main_loop(ext_input = nil) input = ext_input.nil? ? read_line : ext_input result = evaluator.parse(input) if result.eql?('exit') exit elsif result.eql?('checkupdate') check_for_new_release else puts result end end
start(initial_command, extra_command, new_skip, resume_skip)
click to toggle source
# File lib/gemwarrior/repl.rb, line 65 def start(initial_command, extra_command, new_skip, resume_skip) setup_screen(initial_command, extra_command, new_skip, resume_skip) clocker = Clocker.new at_exit do update_duration(clocker.stop) game.update_options_file log_stats(world.duration, world.player) save_game(world) end clocker.clock do # main loop loop do prompt begin main_loop rescue Interrupt puts puts QUIT_MESSAGE exit end end end end
Private Instance Methods
check_for_new_release()
click to toggle source
# File lib/gemwarrior/repl.rb, line 197 def check_for_new_release new_release_available = false puts 'Checking releases...' remote_release = Gems.versions('gemwarrior').first['number'] local_release = Gemwarrior::VERSION 0.upto(2) do |i| if remote_release.split('.')[i].to_i > local_release.split('.')[i].to_i new_release_available = true end end if new_release_available puts "GW v#{remote_release} available! Please exit and run 'gem update' before continuing." puts else puts 'You have the latest version. Fantastic!' puts end end
clear_screen()
click to toggle source
timer observer
def update(command)
main_loop(command)
end
# File lib/gemwarrior/repl.rb, line 111 def clear_screen OS.windows? ? system('cls') : system('clear') end
command_exists?(cmd)
click to toggle source
# File lib/gemwarrior/repl.rb, line 699 def command_exists?(cmd) ENV['PATH'].split(File::PATH_SEPARATOR).collect { |d| Dir.entries d if Dir.exist? d }.flatten.include?(cmd) end
display_log_of_attempts()
click to toggle source
# File lib/gemwarrior/repl.rb, line 175 def display_log_of_attempts if File.exist?(GameOptions.data['log_file_path']) and !File.zero?(GameOptions.data['log_file_path']) File.open(GameOptions.data['log_file_path']).readlines.each do |line| print "#{line}" end if GameOptions.data['debug_mode'] print 'Clear log of attempts? (y/n) ' answer = gets.chomp.downcase case answer when 'y', 'yes' File.truncate(GameOptions.data['log_file_path'], 0) puts 'Log of attempts: erased!' end puts end else puts 'No attempts made yet!' end end
get_save_file_name()
click to toggle source
# File lib/gemwarrior/repl.rb, line 120 def get_save_file_name if save_file_exist? File.open(GameOptions.data['save_file_yaml_path'], 'r') do |f| return YAML.load(f) end end end
load_saved_world(result)
click to toggle source
# File lib/gemwarrior/repl.rb, line 619 def load_saved_world(result) self.world = result self.evaluator = Evaluator.new(self.world) end
log_stats(duration, pl)
click to toggle source
# File lib/gemwarrior/repl.rb, line 486 def log_stats(duration, pl) # display stats upon exit Hr.print('#') print 'Gem Warrior'.colorize(color: :white, background: :black) print " v#{Gemwarrior::VERSION}".colorize(:yellow) print " played for #{duration[:mins].to_s.colorize(color: :white, background: :black)} min(s)" print ", #{duration[:secs].to_s.colorize(color: :white, background: :black)} sec(s)" # print ", and #{duration[:ms].to_s.colorize(color: :white, background: :black)} ms" print "\n" Hr.print('-') print "#{pl.name.ljust(10).colorize(:green)} " print "destroyed #{pl.monsters_killed.to_s.colorize(color: :yellow, background: :black)} monster(s)" print "\n".ljust(12) print "destroyed #{pl.bosses_killed.to_s.colorize(color: :yellow, background: :black)} boss(es)" print "\n".ljust(12) print "picked up #{pl.items_taken.to_s.colorize(color: :yellow, background: :black)} item(s)" print "\n".ljust(12) print "traveled #{pl.movements_made.to_s.colorize(color: :yellow, background: :black)} time(s)" print "\n".ljust(12) print "rested #{pl.rests_taken.to_s.colorize(color: :yellow, background: :black)} time(s)" print "\n".ljust(12) print "died #{pl.deaths.to_s.colorize(color: :yellow, background: :black)} time(s)" print "\n" Hr.print('#') # log stats to file in home directory File.open(GameOptions.data['log_file_path'], 'a') do |f| f.write "#{Time.now} #{pl.name.rjust(13)} - V:#{Gemwarrior::VERSION} LV:#{pl.level} XP:#{pl.xp} $:#{pl.rox} MK:#{pl.monsters_killed} BK:#{pl.bosses_killed} ITM:#{pl.items_taken} MOV:#{pl.movements_made} RST:#{pl.rests_taken} DTH:#{pl.deaths}\n" end end
overwrite_save?()
click to toggle source
# File lib/gemwarrior/repl.rb, line 572 def overwrite_save? mode = GameOptions.data['save_file_mode'] save_file_path = '' if mode.eql? 'Y' save_file_path = GameOptions.data['save_file_yaml_path'] elsif mode.eql? 'M' save_file_path = GameOptions.data['save_file_marshal_path'] end if File.exist?(save_file_path) print 'Overwrite existing save file? (y/n) ' answer = gets.chomp.downcase case answer when 'y', 'yes' puts 'New game started! Press any key to continue.' gets return true else puts 'New game aborted.' return false end end true end
play_intro_tune()
click to toggle source
# File lib/gemwarrior/repl.rb, line 660 def play_intro_tune Audio.play_synth(:intro) end
play_resume_tune()
click to toggle source
# File lib/gemwarrior/repl.rb, line 664 def play_resume_tune Audio.play_synth(:resume_game) end
play_test_tune()
click to toggle source
# File lib/gemwarrior/repl.rb, line 668 def play_test_tune Audio.play_synth(:test) end
print_about_text()
click to toggle source
# File lib/gemwarrior/repl.rb, line 156 def print_about_text puts 'Gem Warrior - A Game of Fortune and Mayhem'.colorize(:yellow) puts '=========================================='.colorize(:yellow) puts 'Gem Warrior is a text adventure roguelike-lite as a RubyGem created by Michael Chadwick (mike@neb.host) and released as open-source on Github. Take on the task set by Queen Ruby to defeat the evil Emerald and get back the ShinyThing(tm) he stole for terrible, dastardly reasons.' puts puts 'Explore the land of Jool with the power of text, fighting enemies to improve your station, grabbing curious items that may or may not come in handy, and finally defeating Mr. Emerald himself to win the game.' end
print_errors()
click to toggle source
# File lib/gemwarrior/repl.rb, line 652 def print_errors if GameOptions.data['errors'] puts "\n\n" puts "Errors: #{GameOptions.data['errors'].colorize(:red)}" GameOptions.data['errors'] = nil end end
print_fortune()
click to toggle source
# File lib/gemwarrior/repl.rb, line 147 def print_fortune noun1_values = WordList.new('noun-plural') noun2_values = WordList.new('noun-plural') noun3_values = WordList.new('noun-plural') puts "* Remember: #{noun1_values.get_random_value.colorize(:yellow)} and #{noun2_values.get_random_value.colorize(:yellow)} are the key to #{noun3_values.get_random_value.colorize(:yellow)} *\n\n" puts end
print_help_text()
click to toggle source
# File lib/gemwarrior/repl.rb, line 164 def print_help_text puts 'Gem Warrior - Some Basic Help Commands'.colorize(:yellow) puts '======================================'.colorize(:yellow) puts '* Basic functions: look, go, character, inventory, attack *' puts '* Type \'help\' while in-game for complete list of commands *' puts '* Most commands can be abbreviated to their first letter *' puts '* Note: if something isn\'t working, try: *' puts '* 1) starting a new game *' puts '* 2) updating the game *' end
print_logo()
click to toggle source
# File lib/gemwarrior/repl.rb, line 132 def print_logo puts '/-+-+-+ +-+-+-+-+-+-+-\\'.colorize(:yellow) puts '|G|E|M| |W|A|R|R|I|O|R|'.colorize(:yellow) puts '\\-+-+-+ +-+-+-+-+-+-+-/'.colorize(:yellow) puts '[[[[[[[DEBUGGING]]]]]]]'.colorize(:white) if GameOptions.data['debug_mode'] end
print_options()
click to toggle source
# File lib/gemwarrior/repl.rb, line 282 def print_options puts puts 'Gem Warrior General Options'.colorize(:yellow) puts '================================='.colorize(:yellow) puts puts 'Change several sound options, whether Wordnik is used to generate more dynamic descriptors of entities (valid WORDNIK_API_KEY environment variable must be set), and if attack/fight commands need to have a target or not (if enabled, will attack first monster in vicinty).' puts puts " (1) SOUND ENABLED : #{GameOptions.data['sound_enabled']}" puts " (2) SOUND SYSTEM : #{GameOptions.data['sound_system']}" puts " (3) SOUND VOLUME : #{GameOptions.data['sound_volume']}" puts " (4) USE WORDNIK : #{GameOptions.data['use_wordnik']}" puts " (5) FIGHT COMPLETION : #{GameOptions.data['fight_completion']}" puts puts '================================='.colorize(:yellow) puts puts 'Enter option number to change value, or any other key to return to main menu.' puts print '[GW_OPTS]> ' answer = STDIN.getch case answer when '1' print answer GameOptions.data['sound_enabled'] = !GameOptions.data['sound_enabled'] print_options when '2' print answer print "\n" print_options_sound_sytem print_options when '3' print answer print "\n" print 'Enter a volume from 0.0 to 1.0: ' new_vol = gets.chomp.to_f.abs if new_vol >= 0.0 and new_vol <= 1.0 GameOptions.data['sound_volume'] = new_vol else puts 'Not a valid volume.' end print_options when '4' print answer GameOptions.data['use_wordnik'] = !GameOptions.data['use_wordnik'] print_options when '5' print answer GameOptions.data['fight_completion'] = !GameOptions.data['fight_completion'] print_options else print answer return end end
print_options_sound_sytem()
click to toggle source
# File lib/gemwarrior/repl.rb, line 218 def print_options_sound_sytem puts puts 'Sound System Selection'.colorize(:yellow) puts '================================='.colorize(:yellow) puts win32 = ' (1) WIN32-SOUND ' OS.windows? ? (print win32) : (print win32.colorize(:light_black)) print '(SELECTED)'.colorize(:yellow) if GameOptions.data['sound_system'].eql?('win32-sound') print "\n" print ' (2) FEEP ' print '(SELECTED)'.colorize(:yellow) if GameOptions.data['sound_system'].eql?('feep') print "\n" print ' (3) BLOOPS ' print '(SELECTED)'.colorize(:yellow) if GameOptions.data['sound_system'].eql?('bloops') print "\n" print "\n" print ' (T) TEST SOUND ' print "\n" puts puts ' WIN32-SOUND : good quality; Windows-only' puts ' FEEP : cross-platform; VERY SLOW and BUGGY' puts ' BLOOPS : cross-platform; requires portaudio' puts puts ' NOTE: none of these are required dependencies anymore, as sound is optional.' puts ' If you do not have the one selected installed on your machine, you will get ' puts ' an error on game load, and no sound will be heard.' puts puts '================================='.colorize(:yellow) puts puts 'Enter option number to select sound system, or any other key to exit.' puts print '[GW_OPTS]-[SOUND_SYSTEM]> ' answer = STDIN.getch.chomp.downcase case answer when '1' if OS.windows? puts answer GameOptions.add 'sound_system', 'win32-sound' else puts end print_options_sound_sytem when '2' puts answer GameOptions.add 'sound_system', 'feep' print_options_sound_sytem when '3' puts answer GameOptions.add 'sound_system', 'bloops' print_options_sound_sytem when 't' puts answer Audio.init play_test_tune print_errors print_options_sound_sytem else puts return end end
print_sound_test()
click to toggle source
# File lib/gemwarrior/repl.rb, line 338 def print_sound_test puts puts 'Gem Warrior Sound Test'.colorize(:yellow) puts '================================='.colorize(:yellow) if GameOptions.data['sound_enabled'] puts puts 'Play all the sounds in Gemwarrior.' puts cues = Audio.get_cues for cue in cues do pp cue[0].to_s end puts puts '================================='.colorize(:yellow) puts puts 'Enter sound id to play it, or enter "x" to return to the main menu.' else GameOptions.data['errors'] = ERROR_SOUND_NOT_ENABLED end print_errors puts print '[GW_SOUND_TEST]> ' answer = gets.chomp.downcase # print answer if answer.eql?('x') return else Audio.play_synth(answer.to_sym) print_sound_test end end
print_splash_message()
click to toggle source
# File lib/gemwarrior/repl.rb, line 139 def print_splash_message SPLASH_MESSAGE.length.times { print '=' } puts puts SPLASH_MESSAGE SPLASH_MESSAGE.length.times { print '=' } puts end
prompt()
click to toggle source
# File lib/gemwarrior/repl.rb, line 672 def prompt prompt_template = "\n" prompt_template += "[LV:%2s][XP:%3s][ROX:%3s][HP:%3s/%-3s] [".colorize(:yellow) prompt_template += "%s".colorize(:green) prompt_template += " @ ".colorize(:yellow) prompt_template += "%s".colorize(:cyan) prompt_template += "]".colorize(:yellow) prompt_template += "[%s, %s, %s]".colorize(:yellow) if GameOptions.data['debug_mode'] prompt_template += "\n" prompt_template += '[c:character][i:inventory][l:look][u:use][t:take]' prompt_vars_arr = [ world.player.level, world.player.xp, world.player.rox, world.player.hp_cur, world.player.hp_max, world.player.name, world.location_by_coords(world.player.cur_coords).name_display ] if GameOptions.data['debug_mode'] prompt_vars_arr.push(world.player.cur_coords[:x], world.player.cur_coords[:y], world.player.cur_coords[:z]) end print (prompt_template % prompt_vars_arr) print "\n" end
puts(s = '', width = GameOptions.data['wrap_width'])
click to toggle source
Calls superclass method
# File lib/gemwarrior/repl.rb, line 128 def puts(s = '', width = GameOptions.data['wrap_width']) super s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n") unless s.nil? end
read_line()
click to toggle source
# File lib/gemwarrior/repl.rb, line 115 def read_line prompt_text = GameOptions.data['debug_mode'] ? ' GW[D]> ' : ' GW> ' Readline.readline(prompt_text, true).to_s end
resume_game()
click to toggle source
# File lib/gemwarrior/repl.rb, line 547 def resume_game mode = GameOptions.data['save_file_mode'] puts 'Resuming game...' if mode.eql? 'Y' if File.exist?(GameOptions.data['save_file_yaml_path']) File.open(GameOptions.data['save_file_yaml_path'], 'r') do |f| return YAML.load(f) end else puts 'No save file exists.' nil end elsif mode.eql? 'M' if File.exist?(GameOptions.data['save_file_marshal_path']) File.open(GameOptions.data['save_file_marshal_path'], 'r') do |f| return Marshal.load(f) end else puts 'No save file exists.' nil end end end
save_file_exist?()
click to toggle source
# File lib/gemwarrior/repl.rb, line 536 def save_file_exist? mode = GameOptions.data['save_file_mode'] if mode.eql? 'Y' File.exist?(GameOptions.data['save_file_yaml_path']) elsif mode.eql? 'M' File.exist?(GameOptions.data['save_file_bin_path']) else false end end
save_game(world)
click to toggle source
# File lib/gemwarrior/repl.rb, line 517 def save_game(world) mode = GameOptions.data['save_file_mode'] puts 'Saving game...' if mode.eql? 'Y' File.open(GameOptions.data['save_file_yaml_path'], 'w') do |f| f.write YAML.dump(world) end elsif mode.eql? 'M' File.open(GameOptions.data['save_file_bin_path'], 'w') do |f| f.write Marshal.dump(world) end else puts 'Error: Save file mode not set. Game not saved.' return end puts 'Game saved!' end
setup_screen(initial_command = nil, extra_command = nil, new_skip = false, resume_skip = false)
click to toggle source
# File lib/gemwarrior/repl.rb, line 624 def setup_screen(initial_command = nil, extra_command = nil, new_skip = false, resume_skip = false) # welcome player to game clear_screen print_logo # main menu loop until new game or exit if new_skip print_errors play_intro_tune print_splash_message print_fortune elsif resume_skip result = resume_game if result.nil? run_main_menu else print_errors load_saved_world(result) end else run_main_menu end # hook to do something right off the bat puts evaluator.parse(initial_command) unless initial_command.nil? puts evaluator.parse(extra_command) unless extra_command.nil? end
update_duration(new_duration)
click to toggle source
# File lib/gemwarrior/repl.rb, line 599 def update_duration(new_duration) new_mins = new_duration[:mins] new_secs = new_duration[:secs] new_ms = new_duration[:ms] world.duration[:mins] += new_mins world.duration[:secs] += new_secs world.duration[:ms] += new_ms if world.duration[:ms] > 1000 world.duration[:secs] += world.duration[:ms] / 1000 world.duration[:ms] = world.duration[:ms] % 1000 end if world.duration[:secs] > 60 world.duration[:mins] += world.duration[:secs] / 60 world.duration[:secs] = world.duration[:secs] % 60 end end