gamebox 0.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.
- data/History.txt +18 -0
 - data/Manifest.txt +85 -0
 - data/README.txt +33 -0
 - data/Rakefile +42 -0
 - data/TODO.txt +29 -0
 - data/bin/gamebox +49 -0
 - data/docs/gamebox04_big.png +0 -0
 - data/docs/getting_started.rdoc +99 -0
 - data/docs/logo.png +0 -0
 - data/lib/gamebox.rb +6 -0
 - data/lib/gamebox/actor.rb +143 -0
 - data/lib/gamebox/actor_factory.rb +64 -0
 - data/lib/gamebox/actor_view.rb +35 -0
 - data/lib/gamebox/ai/line_of_site.rb +61 -0
 - data/lib/gamebox/ai/polaris.rb +107 -0
 - data/lib/gamebox/ai/two_d_grid_location.rb +21 -0
 - data/lib/gamebox/ai/two_d_grid_map.rb +77 -0
 - data/lib/gamebox/aliasing.rb +16 -0
 - data/lib/gamebox/animated.rb +84 -0
 - data/lib/gamebox/behavior.rb +16 -0
 - data/lib/gamebox/config_manager.rb +22 -0
 - data/lib/gamebox/console_app.rb +39 -0
 - data/lib/gamebox/data/fonts/Asimov.ttf +0 -0
 - data/lib/gamebox/data/fonts/GAMEBOX_FONTS_GO_HERE +0 -0
 - data/lib/gamebox/data/graphics/GAMEBOX_GRAPHICS_GO_HERE +0 -0
 - data/lib/gamebox/data/graphics/logo.png +0 -0
 - data/lib/gamebox/data/music/GAMEBOX_MUSIC_GOES_HERE +0 -0
 - data/lib/gamebox/data/sounds/GAMEBOX_SOUND_FX_GO_HERE +0 -0
 - data/lib/gamebox/director.rb +47 -0
 - data/lib/gamebox/gamebox_application.rb +77 -0
 - data/lib/gamebox/graphical.rb +24 -0
 - data/lib/gamebox/graphical_actor_view.rb +31 -0
 - data/lib/gamebox/inflections.rb +52 -0
 - data/lib/gamebox/inflector.rb +278 -0
 - data/lib/gamebox/input_manager.rb +104 -0
 - data/lib/gamebox/layered.rb +34 -0
 - data/lib/gamebox/level.rb +64 -0
 - data/lib/gamebox/linked_list.rb +137 -0
 - data/lib/gamebox/logo.rb +11 -0
 - data/lib/gamebox/metaclass.rb +6 -0
 - data/lib/gamebox/mode.rb +123 -0
 - data/lib/gamebox/mode_manager.rb +80 -0
 - data/lib/gamebox/numbers_ext.rb +3 -0
 - data/lib/gamebox/physical.rb +139 -0
 - data/lib/gamebox/physical_director.rb +17 -0
 - data/lib/gamebox/physical_level.rb +89 -0
 - data/lib/gamebox/physics.rb +27 -0
 - data/lib/gamebox/publisher_ext.rb +13 -0
 - data/lib/gamebox/resource_manager.rb +122 -0
 - data/lib/gamebox/score.rb +35 -0
 - data/lib/gamebox/sorted_list.rb +59 -0
 - data/lib/gamebox/sound_manager.rb +84 -0
 - data/lib/gamebox/surface_ext.rb +37 -0
 - data/lib/gamebox/svg_actor.rb +55 -0
 - data/lib/gamebox/svg_document.rb +160 -0
 - data/lib/gamebox/template_app/README +30 -0
 - data/lib/gamebox/template_app/Rakefile +20 -0
 - data/lib/gamebox/template_app/config/boot.rb +5 -0
 - data/lib/gamebox/template_app/config/environment.rb +29 -0
 - data/lib/gamebox/template_app/config/game.yml +6 -0
 - data/lib/gamebox/template_app/config/mode_level_config.yml +3 -0
 - data/lib/gamebox/template_app/config/objects.yml +29 -0
 - data/lib/gamebox/template_app/data/fonts/FONTS_GO_HERE +0 -0
 - data/lib/gamebox/template_app/data/graphics/GRAPHICS_GO_HERE +0 -0
 - data/lib/gamebox/template_app/data/music/MUSIC_GOES_HERE +0 -0
 - data/lib/gamebox/template_app/data/sounds/SOUND_FX_GO_HERE +0 -0
 - data/lib/gamebox/template_app/doc/README_FOR_APP +1 -0
 - data/lib/gamebox/template_app/lib/code_statistics.rb +107 -0
 - data/lib/gamebox/template_app/lib/diy.rb +371 -0
 - data/lib/gamebox/template_app/lib/platform.rb +16 -0
 - data/lib/gamebox/template_app/src/app.rb +8 -0
 - data/lib/gamebox/template_app/src/demo_level.rb +20 -0
 - data/lib/gamebox/template_app/src/game.rb +22 -0
 - data/lib/gamebox/template_app/src/my_actor.rb +17 -0
 - data/lib/gamebox/version.rb +10 -0
 - data/lib/gamebox/viewport.rb +81 -0
 - data/lib/gamebox/wrapped_screen.rb +15 -0
 - data/script/perf_polaris.rb +36 -0
 - data/test/helper.rb +25 -0
 - data/test/test_actor.rb +38 -0
 - data/test/test_animated.rb +64 -0
 - data/test/test_line_of_site.rb +14 -0
 - data/test/test_physical.rb +26 -0
 - data/test/test_polaris.rb +193 -0
 - data/test/test_viewport.rb +116 -0
 - metadata +188 -0
 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class ConfigManager
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              attr_accessor :settings
         
     | 
| 
      
 4 
     | 
    
         
            +
              constructor :resource_manager
         
     | 
| 
      
 5 
     | 
    
         
            +
              GAME_SETTINGS_FILE = "game"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 8 
     | 
    
         
            +
                @settings = @resource_manager.load_config(GAME_SETTINGS_FILE)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def save
         
     | 
| 
      
 12 
     | 
    
         
            +
                @resource_manager.save_settings(GAME_SETTINGS_FILE, @settings)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def [](key)
         
     | 
| 
      
 16 
     | 
    
         
            +
                @settings[key]
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def []=(key,val)
         
     | 
| 
      
 20 
     | 
    
         
            +
                @settings[key] = val
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            puts "Connecting to game..."
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'irb'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'irb/completion'
         
     | 
| 
      
 4 
     | 
    
         
            +
            module IRB
         
     | 
| 
      
 5 
     | 
    
         
            +
              def IRB.start_session(obj)
         
     | 
| 
      
 6 
     | 
    
         
            +
                unless $irb
         
     | 
| 
      
 7 
     | 
    
         
            +
                  IRB.setup nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ## maybe set some opts here, as in parse_opts in irb/init.rb?
         
     | 
| 
      
 9 
     | 
    
         
            +
                  IRB.load_modules
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
                
         
     | 
| 
      
 12 
     | 
    
         
            +
                workspace = WorkSpace.new(obj)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                if @CONF[:SCRIPT] ## normally, set by parse_opts
         
     | 
| 
      
 15 
     | 
    
         
            +
                  $irb = Irb.new(workspace, @CONF[:SCRIPT])
         
     | 
| 
      
 16 
     | 
    
         
            +
                else
         
     | 
| 
      
 17 
     | 
    
         
            +
                  $irb = Irb.new(workspace)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC]
         
     | 
| 
      
 21 
     | 
    
         
            +
                @CONF[:MAIN_CONTEXT] = $irb.context
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                trap("INT") do
         
     | 
| 
      
 24 
     | 
    
         
            +
                  $irb.signal_handle
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                catch(:IRB_EXIT) do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  $irb.eval_input
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                print "\n"
         
     | 
| 
      
 31 
     | 
    
         
            +
                
         
     | 
| 
      
 32 
     | 
    
         
            +
                ## might want to reset your app's interrupt handler here
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            require 'drb'
         
     | 
| 
      
 37 
     | 
    
         
            +
            DRb.start_service
         
     | 
| 
      
 38 
     | 
    
         
            +
            game = DRbObject.new nil, "druby://localhost:7373"
         
     | 
| 
      
 39 
     | 
    
         
            +
            IRB.start_session game
         
     | 
| 
         Binary file 
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         Binary file 
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Directors manage actors.
         
     | 
| 
      
 2 
     | 
    
         
            +
            class Director
         
     | 
| 
      
 3 
     | 
    
         
            +
              attr_accessor :actors
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 6 
     | 
    
         
            +
                @actors = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                @dead_actors = []
         
     | 
| 
      
 8 
     | 
    
         
            +
                setup
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def add_actor(actor)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @actors << actor
         
     | 
| 
      
 16 
     | 
    
         
            +
                actor.when :remove_me do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  remove_actor actor
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
                actor_added actor
         
     | 
| 
      
 20 
     | 
    
         
            +
                actor
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def remove_actor(actor)
         
     | 
| 
      
 24 
     | 
    
         
            +
                @dead_actors << actor
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def actor_removed(actor)
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def actor_added(actor)
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def empty?
         
     | 
| 
      
 34 
     | 
    
         
            +
                @actors.empty?
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def update(time)
         
     | 
| 
      
 38 
     | 
    
         
            +
                for act in @dead_actors
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @actors.delete act
         
     | 
| 
      
 40 
     | 
    
         
            +
                  actor_removed act
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                @dead_actors = []
         
     | 
| 
      
 43 
     | 
    
         
            +
                for act in @actors
         
     | 
| 
      
 44 
     | 
    
         
            +
                  act.update time if act.alive?
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $: << "#{File.dirname(__FILE__)}/../config"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rubygame'
         
     | 
| 
      
 6 
     | 
    
         
            +
            include Rubygame
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'surface_ext'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            require "environment"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'metaclass'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'publisher'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require 'publisher_ext'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'inflector'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'constructor'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'diy'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'actor_factory'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            class GameboxApp
         
     | 
| 
      
 20 
     | 
    
         
            +
              attr_reader :context, :game
         
     | 
| 
      
 21 
     | 
    
         
            +
              def self.run(argv,env)
         
     | 
| 
      
 22 
     | 
    
         
            +
                GameboxApp.new.start argv, env
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 26 
     | 
    
         
            +
                @context = DIY::Context.from_file(APP_ROOT + '/config/objects.yml')
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 30 
     | 
    
         
            +
                Rubygame.init
         
     | 
| 
      
 31 
     | 
    
         
            +
                @game = @context[:game]
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
      
 33 
     | 
    
         
            +
                @config_manager = @context[:config_manager]
         
     | 
| 
      
 34 
     | 
    
         
            +
                setup_debug_server if @config_manager[:debug_server]
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              def setup_debug_server
         
     | 
| 
      
 38 
     | 
    
         
            +
                
         
     | 
| 
      
 39 
     | 
    
         
            +
                require 'drb'
         
     | 
| 
      
 40 
     | 
    
         
            +
                self.class.extend DRbUndumped
         
     | 
| 
      
 41 
     | 
    
         
            +
                puts "Starting debug server..."
         
     | 
| 
      
 42 
     | 
    
         
            +
                
         
     | 
| 
      
 43 
     | 
    
         
            +
                DRb.start_service "druby://localhost:7373", self
         
     | 
| 
      
 44 
     | 
    
         
            +
                puts "on #{DRb.uri}"
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              def main_loop
         
     | 
| 
      
 48 
     | 
    
         
            +
                @input_manager = @context[:input_manager]
         
     | 
| 
      
 49 
     | 
    
         
            +
                @input_manager.main_loop @game
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              def shutdown
         
     | 
| 
      
 53 
     | 
    
         
            +
                Rubygame.quit
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
              
         
     | 
| 
      
 56 
     | 
    
         
            +
              def debug_eval(eval_str)
         
     | 
| 
      
 57 
     | 
    
         
            +
                instance_eval eval_str
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def start(argv,env)
         
     | 
| 
      
 61 
     | 
    
         
            +
                setup
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                main_loop
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                shutdown
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            # TODO move this to some logging class
         
     | 
| 
      
 70 
     | 
    
         
            +
            def log(output, level = :debug)
         
     | 
| 
      
 71 
     | 
    
         
            +
              t = Time.now
         
     | 
| 
      
 72 
     | 
    
         
            +
              puts "[#{t.min}:#{t.sec}:#{t.usec}] [#{level}] #{output}"
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            if $0 == __FILE__
         
     | 
| 
      
 76 
     | 
    
         
            +
              GameboxApp.run ARGV, ENV
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'behavior'
         
     | 
| 
      
 2 
     | 
    
         
            +
            # keeps track of an image for you based on the actor's class
         
     | 
| 
      
 3 
     | 
    
         
            +
            # by default it expects images to be:
         
     | 
| 
      
 4 
     | 
    
         
            +
            # data/graphics/classname.png
         
     | 
| 
      
 5 
     | 
    
         
            +
            class Graphical < Behavior
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              attr_accessor :image
         
     | 
| 
      
 8 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                @image = @actor.resource_manager.load_actor_image @actor
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                graphical_obj = self
         
     | 
| 
      
 13 
     | 
    
         
            +
                @actor.instance_eval do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  (class << self; self; end).class_eval do
         
     | 
| 
      
 15 
     | 
    
         
            +
                    define_method :image do 
         
     | 
| 
      
 16 
     | 
    
         
            +
                      graphical_obj.image
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    define_method :graphical do 
         
     | 
| 
      
 19 
     | 
    
         
            +
                      graphical_obj
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'actor_view'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class GraphicalActorView < ActorView
         
     | 
| 
      
 4 
     | 
    
         
            +
              def draw(target, x_off, y_off)
         
     | 
| 
      
 5 
     | 
    
         
            +
                debug = false
         
     | 
| 
      
 6 
     | 
    
         
            +
                x = @actor.x
         
     | 
| 
      
 7 
     | 
    
         
            +
                y = @actor.y
         
     | 
| 
      
 8 
     | 
    
         
            +
                img = @actor.image
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                if @actor.is? :animated or @actor.is? :physical
         
     | 
| 
      
 11 
     | 
    
         
            +
                  w,h = *img.size
         
     | 
| 
      
 12 
     | 
    
         
            +
                  x = x-w/2
         
     | 
| 
      
 13 
     | 
    
         
            +
                  y = y-h/2
         
     | 
| 
      
 14 
     | 
    
         
            +
                  img.blit target.screen, [x+x_off,y+y_off]
         
     | 
| 
      
 15 
     | 
    
         
            +
                  
         
     | 
| 
      
 16 
     | 
    
         
            +
                  if @actor.is? :physical and debug
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @actor.physical.shapes.each do |shape|
         
     | 
| 
      
 18 
     | 
    
         
            +
                      bb = shape.bb
         
     | 
| 
      
 19 
     | 
    
         
            +
                      x = bb.l + x_off
         
     | 
| 
      
 20 
     | 
    
         
            +
                      y = bb.b + y_off
         
     | 
| 
      
 21 
     | 
    
         
            +
                      x2 = bb.r + x_off
         
     | 
| 
      
 22 
     | 
    
         
            +
                      y2 = bb.t + y_off
         
     | 
| 
      
 23 
     | 
    
         
            +
                      target.draw_box_s [x,y], [x2,y2], [255,25,25,150]
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  
         
     | 
| 
      
 27 
     | 
    
         
            +
                else
         
     | 
| 
      
 28 
     | 
    
         
            +
                  img.blit target.screen, [x+x_off,y+y_off]
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Inflector.inflections do |inflect|
         
     | 
| 
      
 2 
     | 
    
         
            +
              inflect.plural(/$/, 's')
         
     | 
| 
      
 3 
     | 
    
         
            +
              inflect.plural(/s$/i, 's')
         
     | 
| 
      
 4 
     | 
    
         
            +
              inflect.plural(/(ax|test)is$/i, '\1es')
         
     | 
| 
      
 5 
     | 
    
         
            +
              inflect.plural(/(octop|vir)us$/i, '\1i')
         
     | 
| 
      
 6 
     | 
    
         
            +
              inflect.plural(/(alias|status)$/i, '\1es')
         
     | 
| 
      
 7 
     | 
    
         
            +
              inflect.plural(/(bu)s$/i, '\1ses')
         
     | 
| 
      
 8 
     | 
    
         
            +
              inflect.plural(/(buffal|tomat)o$/i, '\1oes')
         
     | 
| 
      
 9 
     | 
    
         
            +
              inflect.plural(/([ti])um$/i, '\1a')
         
     | 
| 
      
 10 
     | 
    
         
            +
              inflect.plural(/sis$/i, 'ses')
         
     | 
| 
      
 11 
     | 
    
         
            +
              inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
         
     | 
| 
      
 12 
     | 
    
         
            +
              inflect.plural(/(hive)$/i, '\1s')
         
     | 
| 
      
 13 
     | 
    
         
            +
              inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
         
     | 
| 
      
 14 
     | 
    
         
            +
              inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
         
     | 
| 
      
 15 
     | 
    
         
            +
              inflect.plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
         
     | 
| 
      
 16 
     | 
    
         
            +
              inflect.plural(/([m|l])ouse$/i, '\1ice')
         
     | 
| 
      
 17 
     | 
    
         
            +
              inflect.plural(/^(ox)$/i, '\1en')
         
     | 
| 
      
 18 
     | 
    
         
            +
              inflect.plural(/(quiz)$/i, '\1zes')
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              inflect.singular(/s$/i, '')
         
     | 
| 
      
 21 
     | 
    
         
            +
              inflect.singular(/(n)ews$/i, '\1ews')
         
     | 
| 
      
 22 
     | 
    
         
            +
              inflect.singular(/([ti])a$/i, '\1um')
         
     | 
| 
      
 23 
     | 
    
         
            +
              inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
         
     | 
| 
      
 24 
     | 
    
         
            +
              inflect.singular(/(^analy)ses$/i, '\1sis')
         
     | 
| 
      
 25 
     | 
    
         
            +
              inflect.singular(/([^f])ves$/i, '\1fe')
         
     | 
| 
      
 26 
     | 
    
         
            +
              inflect.singular(/(hive)s$/i, '\1')
         
     | 
| 
      
 27 
     | 
    
         
            +
              inflect.singular(/(tive)s$/i, '\1')
         
     | 
| 
      
 28 
     | 
    
         
            +
              inflect.singular(/([lr])ves$/i, '\1f')
         
     | 
| 
      
 29 
     | 
    
         
            +
              inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
         
     | 
| 
      
 30 
     | 
    
         
            +
              inflect.singular(/(s)eries$/i, '\1eries')
         
     | 
| 
      
 31 
     | 
    
         
            +
              inflect.singular(/(m)ovies$/i, '\1ovie')
         
     | 
| 
      
 32 
     | 
    
         
            +
              inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
         
     | 
| 
      
 33 
     | 
    
         
            +
              inflect.singular(/([m|l])ice$/i, '\1ouse')
         
     | 
| 
      
 34 
     | 
    
         
            +
              inflect.singular(/(bus)es$/i, '\1')
         
     | 
| 
      
 35 
     | 
    
         
            +
              inflect.singular(/(o)es$/i, '\1')
         
     | 
| 
      
 36 
     | 
    
         
            +
              inflect.singular(/(shoe)s$/i, '\1')
         
     | 
| 
      
 37 
     | 
    
         
            +
              inflect.singular(/(cris|ax|test)es$/i, '\1is')
         
     | 
| 
      
 38 
     | 
    
         
            +
              inflect.singular(/(octop|vir)i$/i, '\1us')
         
     | 
| 
      
 39 
     | 
    
         
            +
              inflect.singular(/(alias|status)es$/i, '\1')
         
     | 
| 
      
 40 
     | 
    
         
            +
              inflect.singular(/^(ox)en/i, '\1')
         
     | 
| 
      
 41 
     | 
    
         
            +
              inflect.singular(/(vert|ind)ices$/i, '\1ex')
         
     | 
| 
      
 42 
     | 
    
         
            +
              inflect.singular(/(matr)ices$/i, '\1ix')
         
     | 
| 
      
 43 
     | 
    
         
            +
              inflect.singular(/(quiz)zes$/i, '\1')
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              inflect.irregular('person', 'people')
         
     | 
| 
      
 46 
     | 
    
         
            +
              inflect.irregular('man', 'men')
         
     | 
| 
      
 47 
     | 
    
         
            +
              inflect.irregular('child', 'children')
         
     | 
| 
      
 48 
     | 
    
         
            +
              inflect.irregular('sex', 'sexes')
         
     | 
| 
      
 49 
     | 
    
         
            +
              inflect.irregular('move', 'moves')
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              inflect.uncountable(%w(equipment information rice money species series fish sheep))
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,278 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'singleton'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
         
     | 
| 
      
 4 
     | 
    
         
            +
            # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
         
     | 
| 
      
 5 
     | 
    
         
            +
            # in inflections.rb.
         
     | 
| 
      
 6 
     | 
    
         
            +
            module Inflector
         
     | 
| 
      
 7 
     | 
    
         
            +
              # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
         
     | 
| 
      
 8 
     | 
    
         
            +
              # inflection rules. Examples:
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   Inflector.inflections do |inflect|
         
     | 
| 
      
 11 
     | 
    
         
            +
              #     inflect.plural /^(ox)$/i, '\1\2en'
         
     | 
| 
      
 12 
     | 
    
         
            +
              #     inflect.singular /^(ox)en/i, '\1'
         
     | 
| 
      
 13 
     | 
    
         
            +
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              #     inflect.irregular 'octopus', 'octopi'
         
     | 
| 
      
 15 
     | 
    
         
            +
              #
         
     | 
| 
      
 16 
     | 
    
         
            +
              #     inflect.uncountable "equipment"
         
     | 
| 
      
 17 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
         
     | 
| 
      
 20 
     | 
    
         
            +
              # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
         
     | 
| 
      
 21 
     | 
    
         
            +
              # already have been loaded.
         
     | 
| 
      
 22 
     | 
    
         
            +
              class Inflections
         
     | 
| 
      
 23 
     | 
    
         
            +
                include Singleton
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                attr_reader :plurals, :singulars, :uncountables
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @plurals, @singulars, @uncountables = [], [], []
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
         
     | 
| 
      
 32 
     | 
    
         
            +
                # The replacement should always be a string that may include references to the matched data from the rule.
         
     | 
| 
      
 33 
     | 
    
         
            +
                def plural(rule, replacement)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @plurals.insert(0, [rule, replacement])
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
         
     | 
| 
      
 38 
     | 
    
         
            +
                # The replacement should always be a string that may include references to the matched data from the rule.
         
     | 
| 
      
 39 
     | 
    
         
            +
                def singular(rule, replacement)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @singulars.insert(0, [rule, replacement])
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
         
     | 
| 
      
 44 
     | 
    
         
            +
                # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
         
     | 
| 
      
 45 
     | 
    
         
            +
                #
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Examples:
         
     | 
| 
      
 47 
     | 
    
         
            +
                #   irregular 'octopus', 'octopi'
         
     | 
| 
      
 48 
     | 
    
         
            +
                #   irregular 'person', 'people'
         
     | 
| 
      
 49 
     | 
    
         
            +
                def irregular(singular, plural)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
         
     | 
| 
      
 51 
     | 
    
         
            +
                  singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                # Add uncountable words that shouldn't be attempted inflected.
         
     | 
| 
      
 55 
     | 
    
         
            +
                #
         
     | 
| 
      
 56 
     | 
    
         
            +
                # Examples:
         
     | 
| 
      
 57 
     | 
    
         
            +
                #   uncountable "money"
         
     | 
| 
      
 58 
     | 
    
         
            +
                #   uncountable "money", "information"
         
     | 
| 
      
 59 
     | 
    
         
            +
                #   uncountable %w( money information rice )
         
     | 
| 
      
 60 
     | 
    
         
            +
                def uncountable(*words)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  (@uncountables << words).flatten!
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
         
     | 
| 
      
 65 
     | 
    
         
            +
                # the options are: :plurals, :singulars, :uncountables
         
     | 
| 
      
 66 
     | 
    
         
            +
                #
         
     | 
| 
      
 67 
     | 
    
         
            +
                # Examples:
         
     | 
| 
      
 68 
     | 
    
         
            +
                #   clear :all
         
     | 
| 
      
 69 
     | 
    
         
            +
                #   clear :plurals
         
     | 
| 
      
 70 
     | 
    
         
            +
                def clear(scope = :all)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  case scope
         
     | 
| 
      
 72 
     | 
    
         
            +
                    when :all
         
     | 
| 
      
 73 
     | 
    
         
            +
                      @plurals, @singulars, @uncountables = [], [], []
         
     | 
| 
      
 74 
     | 
    
         
            +
                    else
         
     | 
| 
      
 75 
     | 
    
         
            +
                      instance_variable_set "@#{scope}", []
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              extend self
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              def inflections
         
     | 
| 
      
 83 
     | 
    
         
            +
                if block_given?
         
     | 
| 
      
 84 
     | 
    
         
            +
                  yield Inflections.instance
         
     | 
| 
      
 85 
     | 
    
         
            +
                else
         
     | 
| 
      
 86 
     | 
    
         
            +
                  Inflections.instance
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              # Returns the plural form of the word in the string.
         
     | 
| 
      
 91 
     | 
    
         
            +
              #
         
     | 
| 
      
 92 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 93 
     | 
    
         
            +
              #   "post".pluralize #=> "posts"
         
     | 
| 
      
 94 
     | 
    
         
            +
              #   "octopus".pluralize #=> "octopi"
         
     | 
| 
      
 95 
     | 
    
         
            +
              #   "sheep".pluralize #=> "sheep"
         
     | 
| 
      
 96 
     | 
    
         
            +
              #   "words".pluralize #=> "words"
         
     | 
| 
      
 97 
     | 
    
         
            +
              #   "the blue mailman".pluralize #=> "the blue mailmen"
         
     | 
| 
      
 98 
     | 
    
         
            +
              #   "CamelOctopus".pluralize #=> "CamelOctopi"
         
     | 
| 
      
 99 
     | 
    
         
            +
              def pluralize(word)
         
     | 
| 
      
 100 
     | 
    
         
            +
                result = word.to_s.dup
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                if inflections.uncountables.include?(result.downcase)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  result
         
     | 
| 
      
 104 
     | 
    
         
            +
                else
         
     | 
| 
      
 105 
     | 
    
         
            +
                  inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
         
     | 
| 
      
 106 
     | 
    
         
            +
                  result
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
              # The reverse of pluralize, returns the singular form of a word in a string.
         
     | 
| 
      
 111 
     | 
    
         
            +
              #
         
     | 
| 
      
 112 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 113 
     | 
    
         
            +
              #   "posts".singularize #=> "post"
         
     | 
| 
      
 114 
     | 
    
         
            +
              #   "octopi".singularize #=> "octopus"
         
     | 
| 
      
 115 
     | 
    
         
            +
              #   "sheep".singluarize #=> "sheep"
         
     | 
| 
      
 116 
     | 
    
         
            +
              #   "word".singluarize #=> "word"
         
     | 
| 
      
 117 
     | 
    
         
            +
              #   "the blue mailmen".singularize #=> "the blue mailman"
         
     | 
| 
      
 118 
     | 
    
         
            +
              #   "CamelOctopi".singularize #=> "CamelOctopus"
         
     | 
| 
      
 119 
     | 
    
         
            +
              def singularize(word)
         
     | 
| 
      
 120 
     | 
    
         
            +
                result = word.to_s.dup
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                if inflections.uncountables.include?(result.downcase)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  result
         
     | 
| 
      
 124 
     | 
    
         
            +
                else
         
     | 
| 
      
 125 
     | 
    
         
            +
                  inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
         
     | 
| 
      
 126 
     | 
    
         
            +
                  result
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
              end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
              # By default, camelize converts strings to UpperCamelCase. If the argument to camelize
         
     | 
| 
      
 131 
     | 
    
         
            +
              # is set to ":lower" then camelize produces lowerCamelCase.
         
     | 
| 
      
 132 
     | 
    
         
            +
              #
         
     | 
| 
      
 133 
     | 
    
         
            +
              # camelize will also convert '/' to '::' which is useful for converting paths to namespaces
         
     | 
| 
      
 134 
     | 
    
         
            +
              #
         
     | 
| 
      
 135 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 136 
     | 
    
         
            +
              #   "active_record".camelize #=> "ActiveRecord"
         
     | 
| 
      
 137 
     | 
    
         
            +
              #   "active_record".camelize(:lower) #=> "activeRecord"
         
     | 
| 
      
 138 
     | 
    
         
            +
              #   "active_record/errors".camelize #=> "ActiveRecord::Errors"
         
     | 
| 
      
 139 
     | 
    
         
            +
              #   "active_record/errors".camelize(:lower) #=> "activeRecord::Errors"
         
     | 
| 
      
 140 
     | 
    
         
            +
              def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
         
     | 
| 
      
 141 
     | 
    
         
            +
                if first_letter_in_uppercase
         
     | 
| 
      
 142 
     | 
    
         
            +
                  lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
         
     | 
| 
      
 143 
     | 
    
         
            +
                else
         
     | 
| 
      
 144 
     | 
    
         
            +
                  lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              # Capitalizes all the words and replaces some characters in the string to create
         
     | 
| 
      
 149 
     | 
    
         
            +
              # a nicer looking title. Titleize is meant for creating pretty output. It is not
         
     | 
| 
      
 150 
     | 
    
         
            +
              # used in the Rails internals.
         
     | 
| 
      
 151 
     | 
    
         
            +
              #
         
     | 
| 
      
 152 
     | 
    
         
            +
              # titleize is also aliased as as titlecase
         
     | 
| 
      
 153 
     | 
    
         
            +
              #
         
     | 
| 
      
 154 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 155 
     | 
    
         
            +
              #   "man from the boondocks".titleize #=> "Man From The Boondocks"
         
     | 
| 
      
 156 
     | 
    
         
            +
              #   "x-men: the last stand".titleize #=> "X Men: The Last Stand"
         
     | 
| 
      
 157 
     | 
    
         
            +
              def titleize(word)
         
     | 
| 
      
 158 
     | 
    
         
            +
                humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize }
         
     | 
| 
      
 159 
     | 
    
         
            +
              end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              # The reverse of +camelize+. Makes an underscored form from the expression in the string.
         
     | 
| 
      
 162 
     | 
    
         
            +
              #
         
     | 
| 
      
 163 
     | 
    
         
            +
              # Changes '::' to '/' to convert namespaces to paths.
         
     | 
| 
      
 164 
     | 
    
         
            +
              #
         
     | 
| 
      
 165 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 166 
     | 
    
         
            +
              #   "ActiveRecord".underscore #=> "active_record"
         
     | 
| 
      
 167 
     | 
    
         
            +
              #   "ActiveRecord::Errors".underscore #=> active_record/errors
         
     | 
| 
      
 168 
     | 
    
         
            +
              def underscore(camel_cased_word)
         
     | 
| 
      
 169 
     | 
    
         
            +
                camel_cased_word.to_s.gsub(/::/, '/').
         
     | 
| 
      
 170 
     | 
    
         
            +
                  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
         
     | 
| 
      
 171 
     | 
    
         
            +
                  gsub(/([a-z\d])([A-Z])/,'\1_\2').
         
     | 
| 
      
 172 
     | 
    
         
            +
                  tr("-", "_").
         
     | 
| 
      
 173 
     | 
    
         
            +
                  downcase
         
     | 
| 
      
 174 
     | 
    
         
            +
              end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
              # Replaces underscores with dashes in the string.
         
     | 
| 
      
 177 
     | 
    
         
            +
              #
         
     | 
| 
      
 178 
     | 
    
         
            +
              # Example
         
     | 
| 
      
 179 
     | 
    
         
            +
              #   "puni_puni" #=> "puni-puni"
         
     | 
| 
      
 180 
     | 
    
         
            +
              def dasherize(underscored_word)
         
     | 
| 
      
 181 
     | 
    
         
            +
                underscored_word.gsub(/_/, '-')
         
     | 
| 
      
 182 
     | 
    
         
            +
              end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
              # Capitalizes the first word and turns underscores into spaces and strips _id.
         
     | 
| 
      
 185 
     | 
    
         
            +
              # Like titleize, this is meant for creating pretty output.
         
     | 
| 
      
 186 
     | 
    
         
            +
              #
         
     | 
| 
      
 187 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 188 
     | 
    
         
            +
              #   "employee_salary" #=> "Employee salary"
         
     | 
| 
      
 189 
     | 
    
         
            +
              #   "author_id" #=> "Author"
         
     | 
| 
      
 190 
     | 
    
         
            +
              def humanize(lower_case_and_underscored_word)
         
     | 
| 
      
 191 
     | 
    
         
            +
                lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
         
     | 
| 
      
 192 
     | 
    
         
            +
              end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
              # Removes the module part from the expression in the string
         
     | 
| 
      
 195 
     | 
    
         
            +
              #
         
     | 
| 
      
 196 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 197 
     | 
    
         
            +
              #   "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
         
     | 
| 
      
 198 
     | 
    
         
            +
              #   "Inflections".demodulize #=> "Inflections"
         
     | 
| 
      
 199 
     | 
    
         
            +
              def demodulize(class_name_in_module)
         
     | 
| 
      
 200 
     | 
    
         
            +
                class_name_in_module.to_s.gsub(/^.*::/, '')
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
              # Create the name of a table like Rails does for models to table names. This method
         
     | 
| 
      
 204 
     | 
    
         
            +
              # uses the pluralize method on the last word in the string.
         
     | 
| 
      
 205 
     | 
    
         
            +
              #
         
     | 
| 
      
 206 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 207 
     | 
    
         
            +
              #   "RawScaledScorer".tableize #=> "raw_scaled_scorers"
         
     | 
| 
      
 208 
     | 
    
         
            +
              #   "egg_and_ham".tableize #=> "egg_and_hams"
         
     | 
| 
      
 209 
     | 
    
         
            +
              #   "fancyCategory".tableize #=> "fancy_categories"
         
     | 
| 
      
 210 
     | 
    
         
            +
              def tableize(class_name)
         
     | 
| 
      
 211 
     | 
    
         
            +
                pluralize(underscore(class_name))
         
     | 
| 
      
 212 
     | 
    
         
            +
              end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
              # Create a class name from a table name like Rails does for table names to models.
         
     | 
| 
      
 215 
     | 
    
         
            +
              # Note that this returns a string and not a Class. (To convert to an actual class
         
     | 
| 
      
 216 
     | 
    
         
            +
              # follow classify with constantize.)
         
     | 
| 
      
 217 
     | 
    
         
            +
              #
         
     | 
| 
      
 218 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 219 
     | 
    
         
            +
              #   "egg_and_hams".classify #=> "EggAndHam"
         
     | 
| 
      
 220 
     | 
    
         
            +
              #   "post".classify #=> "Post"
         
     | 
| 
      
 221 
     | 
    
         
            +
              def classify(table_name)
         
     | 
| 
      
 222 
     | 
    
         
            +
                # strip out any leading schema name
         
     | 
| 
      
 223 
     | 
    
         
            +
                camelize(singularize(table_name.to_s.sub(/.*\./, '')))
         
     | 
| 
      
 224 
     | 
    
         
            +
              end
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
              # Creates a foreign key name from a class name.
         
     | 
| 
      
 227 
     | 
    
         
            +
              # +separate_class_name_and_id_with_underscore+ sets whether
         
     | 
| 
      
 228 
     | 
    
         
            +
              # the method should put '_' between the name and 'id'.
         
     | 
| 
      
 229 
     | 
    
         
            +
              #
         
     | 
| 
      
 230 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 231 
     | 
    
         
            +
              #   "Message".foreign_key #=> "message_id"
         
     | 
| 
      
 232 
     | 
    
         
            +
              #   "Message".foreign_key(false) #=> "messageid"
         
     | 
| 
      
 233 
     | 
    
         
            +
              #   "Admin::Post".foreign_key #=> "post_id"
         
     | 
| 
      
 234 
     | 
    
         
            +
              def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
         
     | 
| 
      
 235 
     | 
    
         
            +
                underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
         
     | 
| 
      
 236 
     | 
    
         
            +
              end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
              # Constantize tries to find a declared constant with the name specified
         
     | 
| 
      
 239 
     | 
    
         
            +
              # in the string. It raises a NameError when the name is not in CamelCase
         
     | 
| 
      
 240 
     | 
    
         
            +
              # or is not initialized.
         
     | 
| 
      
 241 
     | 
    
         
            +
              #
         
     | 
| 
      
 242 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 243 
     | 
    
         
            +
              #   "Module".constantize #=> Module
         
     | 
| 
      
 244 
     | 
    
         
            +
              #   "Class".constantize #=> Class
         
     | 
| 
      
 245 
     | 
    
         
            +
              def constantize(camel_cased_word)
         
     | 
| 
      
 246 
     | 
    
         
            +
                unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
         
     | 
| 
      
 247 
     | 
    
         
            +
                  raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
         
     | 
| 
      
 248 
     | 
    
         
            +
                end
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                Object.module_eval("::#{$1}", __FILE__, __LINE__)
         
     | 
| 
      
 251 
     | 
    
         
            +
              end
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
              # Ordinalize turns a number into an ordinal string used to denote the
         
     | 
| 
      
 254 
     | 
    
         
            +
              # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
         
     | 
| 
      
 255 
     | 
    
         
            +
              #
         
     | 
| 
      
 256 
     | 
    
         
            +
              # Examples
         
     | 
| 
      
 257 
     | 
    
         
            +
              #   ordinalize(1)     # => "1st"
         
     | 
| 
      
 258 
     | 
    
         
            +
              #   ordinalize(2)     # => "2nd"
         
     | 
| 
      
 259 
     | 
    
         
            +
              #   ordinalize(1002)  # => "1002nd"
         
     | 
| 
      
 260 
     | 
    
         
            +
              #   ordinalize(1003)  # => "1003rd"
         
     | 
| 
      
 261 
     | 
    
         
            +
              def ordinalize(number)
         
     | 
| 
      
 262 
     | 
    
         
            +
                if (11..13).include?(number.to_i % 100)
         
     | 
| 
      
 263 
     | 
    
         
            +
                  "#{number}th"
         
     | 
| 
      
 264 
     | 
    
         
            +
                else
         
     | 
| 
      
 265 
     | 
    
         
            +
                  case number.to_i % 10
         
     | 
| 
      
 266 
     | 
    
         
            +
                    when 1
         
     | 
| 
      
 267 
     | 
    
         
            +
                       "#{number}st"
         
     | 
| 
      
 268 
     | 
    
         
            +
                    when 2
         
     | 
| 
      
 269 
     | 
    
         
            +
                       "#{number}nd"
         
     | 
| 
      
 270 
     | 
    
         
            +
                    when 3
         
     | 
| 
      
 271 
     | 
    
         
            +
                       "#{number}rd"
         
     | 
| 
      
 272 
     | 
    
         
            +
                    else    "#{number}th"
         
     | 
| 
      
 273 
     | 
    
         
            +
                  end
         
     | 
| 
      
 274 
     | 
    
         
            +
                end
         
     | 
| 
      
 275 
     | 
    
         
            +
              end
         
     | 
| 
      
 276 
     | 
    
         
            +
            end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
            require 'inflections'
         
     |