class Automap # syntax: Automap.new(some_room, [(-10..10), (-5, 5)]) # rng_arr should be an array of two ranges. The map'd x/y range from origin, or the room passed. def initialize room, rng_arr, options={:full_traverse=>false, :range=>rng_arr} @pallete = {} @rng_arr = rng_arr options[:yield_range] = rng_arr # passes this to the algorithm that determines what is yielded. build_map(room, options) end #construct the pallete based on the first room. Use a bfs. def build_map(room, opts={:full_traverse=>false}) # commit this room to the map. def write_room(xy, croom) node_data = {:room=>croom, :path=>croom.sector, :wall=>Sector.lookup(croom.sector).symbolw} croom.each_dir do |ex| node_data[ex.direction.exit_code_to_s.to_sym] = ex end @pallete[xy] = node_data # commit our changes. end # parse each room in bfs pattern and only commit rooms which actually are in the target radius. room.each_bfs(opts) do |current_room, context| coord = [context[:x], context[:y]] # this rooms coordinate position. write_room coord, current_room end end # used to find rooms in relationship to the seed room. # returns the node containing the data for this coordinate. def find xy @pallete[xy] end # convert a section of the pallete over so we can view it. # exammple: map.view ch # defaults to the same view range as it was constructed with. def view ch, rng_arr=@rng_arr xrng, yrng = @rng_arr # bust the array to access it easier. main_str = "" # convert the symbol for the pass into a line that can be translated into a string with gsub. def value_for_pass this_node, p, xy, player str = '000' str = '010' if p == 1 # if it's the second pass. return ' ' if !this_node case p when 0 if this_node[:north] str[1] = '1' str[0] = '1' if (this_node[:west] && !this_node[:west].flags.is_set?(:has_door)) && (!this_node[:north].flags.is_set?(:has_door)) str[2] = '1' if (this_node[:east] && !this_node[:east].flags.is_set?(:has_door)) && (!this_node[:north].flags.is_set?(:has_door)) str = '040' if this_node[:north].flags_state.is_set?(:closed) end when 1 if this_node[:west] str[0] = '1' str[0] = '5' if this_node[:west].flags_state.is_set?(:closed) end str[1] = '2' if xy == [0,0] str[1] = '3' if this_node[:room] == player.in_room str[2] = '1' if this_node[:east] str[2] = '5' if this_node[:east] && this_node[:east].flags_state.is_set?(:closed) when 2 if this_node[:south] str[1] = '1' str[0] = '1' if this_node[:west] && !this_node[:west].flags.is_set(:has_door) && !this_node[:south].flags.is_set?(:has_door) str[2] = '1' if this_node[:east] && !this_node[:east].flags.is_set(:has_door) && !this_node[:south].flags.is_set?(:has_door) str = '040' if this_node[:south].flags_state.is_set?(:closed) end end str.gsub!(/[0]/, this_node[:wall].sect_to_str) str.gsub!(/[1]/, this_node[:path].sect_to_str) str.gsub!(/[3]/, :sect_self.sect_to_str) str.gsub!(/[2]/, :track_found.sect_to_str) str.gsub!(/[4]/, :door_ns.sect_to_str) str.gsub!(/[5]/, :door_we.sect_to_str) return str end ground_zero = @pallete[[0,0]][:room] # the room at ground zero. if ground_zero.name != DEFAULT_STRING name = "[#B"+ ground_zero.name + "#D]" else name = "-" end # actual display logic ch.text_to_player ("#{ground_zero}" + ENDL) if ch.is_imm? ch.text_to_player ("#W O #D,%s, #WO" % name.center(xrng.count*3-2, '-')) + ENDL (yrng).to_a.reverse.each do |y| 3.times do |pass| main_str << "#D|||" xrng.each do |x| # 3 blocks per pass to form the 3x3 mapper. this_node = @pallete[[x, y]] if pass == 2 && y == yrng.first && (x == xrng.first || x == xrng.first+1) next if x == xrng.first+1 main_str << "#RExits:" else main_str << value_for_pass(this_node, pass, [x,y], ch) end end main_str << "#D|||" + ENDL end end buf = "#D[#B" if ch.in_room.exit_list.empty? buf << " None#D ]" else ch.in_room.exit_list.each do |xexit| if xexit buf << (" #{mxptag('send')}#W%s#{mxptag('/send')}" % xexit.direction.exit_code_to_s) end end buf << "#D ]" end main_str << ("#W @ #D'%s'#W @\r\n" % "#{buf}".center(xrng.count*3-2, '-')) ch.text_to_player main_str end def self.offset xy, dir arr = xy.dup case dir when 0 then arr[1] += 1 when 1 then arr[0] += 1 when 2 then arr[1] -= 1 when 3 then arr[0] -= 1 end return arr end end