View Single Post
  #20    
Old April 15th, 2013 (1:41 AM). Edited April 15th, 2013 by Rayquaza..
Rayquaza.'s Avatar
Rayquaza. Rayquaza. is offline
Lead Dev in Pokémon Chaos
     
    Join Date: Sep 2011
    Location: United Kingdom
    Age: 20
    Gender: Male
    Nature: Adamant
    Posts: 688
    Precisely, using that graphic that you attached would be ideal. If I remember rightly CNG also made a dual screen script that put the map on the bottom and parralaxes at the top.

    Just found something useful here. It's a random dungeon generator for VX (I think) with instructions that are to complicated for me to understand but I think others may be able to.

    Spoiler:
    Code:
    #===============================================================================
    # Roguelike Random Dungeon Generator
    #-------------------------------------------------------------------------------
    # Version: 2.0a
    # Author: cozziekuns (rmrk)
    # Last Date Updated: 4/11/2011
    #===============================================================================
    # Description:
    #-------------------------------------------------------------------------------
    # A random dungeon generator akin to that of games like Rogue or Pokemon Mystery
    # Dungeon.
    #===============================================================================
    # Updates
    # ------------------------------------------------------------------------------
    # o 16/07/2011 - Started Script
    # o 17/07/2011 - Updated Script to support black outlines and some autotile 
    #                features
    # o 15/09/2011 - Bugfix.
    # o 17/09/2011 - Major overhaul of the entire script. Now has fully functional
    #                autotile support, and a much faster algorithm that can create a 
    #                500 * 500 tile map with 1000 features in less than 10 seconds.
    #===============================================================================
    # To-do List
    #------------------------------------------------------------------------------- 
    # o Nothing! Suggest some features.
    #===============================================================================
    # Instructions
    #-------------------------------------------------------------------------------
    # Copy and paste this script above ? Main Process but below ? Materials, and
    # edit the modules to your liking. Some difficult modules have links to the 
    # instructions.
    #===============================================================================
    # Maps
    #-------------------------------------------------------------------------------
    # Start editing at:
    #   case id
    #   when [id] - Replace [id] with your map id.
    #     ROOM_MIN_WIDTH : Minimum width for a single "Room"
    #     ROOM_MAX_WIDTH : Maximum width for a single "Room"
    #     ROOM_MIN_HEIGHT : Minimum height for a single "Room"
    #     ROOM_MAX_HEIGHT : Maximum height for a single "Room"
    #     FEATURES : How many features you want to fit in the map
    #     WALL_TILE : Tile of the wall
    #     FLOOR_TILE : Tile of the floor
    #     BLACK_OUTLINE : Do you want a black outline surrounding your random 
    #                     dungeon (slow).
    #   end
    #===============================================================================
    
    module COZZIEKUNS
      
      module RDG
        
        def self.map_settings(id)
          case id
          when 1
            room_min_width = 3
            room_max_width = 6
            room_min_height = 3
            room_max_height = 6
            features = 200
            wall_tile = 0
            floor_tile = 16
            black_outline = false
          when 2
            room_min_width = 4
            room_max_width = 8
            room_min_height = 4
            room_max_height = 8
            features = 75
            wall_tile = 6
            floor_tile = 52
            black_outline = false
          end
          return [room_min_width, room_max_width, room_min_height, room_max_height,
          features, wall_tile, floor_tile, black_outline].compact 
        end
      
      end
      
    end
    
    #==============================================================================
    # ** Game_Map
    #==============================================================================
    
    class Game_Map 
      
      alias coz_rdg_gm_setup setup
      def setup(*args)
        coz_rdg_gm_setup(*args)
        create_dungeon if not COZZIEKUNS::RDG.map_settings(@map_id).empty?
      end
      
      def create_dungeon
        set_variables
        fill_wall_tiles
        dig_random_room
        for i in 0...@features
          count = 0
          loop do
            count += 1
            choose_next_wall
            make_new_feature
            break if @can_make or count == 5
          end
        end
        refine_tilemap
        set_player_and_events
      end
      
      def set_variables
        settings = COZZIEKUNS::RDG.map_settings(@map_id)
        @rmiw = settings[0]
        @rmaw = settings[1]
        @rmih = settings[2]
        @rmah = settings[3]
        @features = settings[4]
        @walls = []
        @floor = []
        @next_wall = []
        @wall_tile = (settings[5] + 80) * 48 + 2048
        @wall2_tile = (settings[5] + 88) * 48 + 2048
        @floor_tile = (settings[6] + 128) + 1408
        @black_outline = settings[7]
        @next_feature = 0
        @can_make = false
        @player_transfered = false
      end
      
      def set_player_and_events
        for event in $game_map.events.values + [$game_player]
          loop do
            ax = @floor[rand(@floor.size)][0]
            ay = @floor[rand(@floor.size)][1]
            if passable_in_area?(ax - 1, ay - 1, event)
              event.moveto(ax, ay)
              break
            end
          end
        end
      end
      
      alias coz_rdg_gm_update update
      def update
        coz_rdg_gm_update
        unless @player_transfered or COZZIEKUNS::RDG.map_settings(@map_id).empty?
          @player_transfered = true
          set_player_and_events
        end
      end
      
      def passable_in_area?(x, y, char, width = 3, height = 3)
        for i in x...x + width; for j in y...y + height
          return false if not char.passable?(i, j)
        end; end
        return true
      end
      
      def fill_wall_tiles
        for i in 0...width; for j in 0...height
          @map.data[i, j, 0] = @wall_tile
        end; end
      end
      
      def dig_random_room
        x = [rand(width) + 1, width - @rmaw - 1].min
        y = [rand(height) + 1, height - @rmah - 1].min
        dig_room(x, y)
      end
      
      def dig_room(x, y, direction = 2)
        width = rand(@rmiw) + @rmaw - @rmiw + 1
        height = rand(@rmih) + @rmah - @rmih + 1
        for i in 0...width
          for j in 0...height
            case direction
            when 0; new_x = x + j; new_y = y + i
            when 1; new_x = x - i; new_y = y + j
            when 2; new_x = x + i; new_y = y + j
            when 3; new_x = x + j; new_y = y - i
            end
            @map.data[new_x, new_y, 0] = @floor_tile
            @floor.push([new_x, new_y]) 
            @walls.push([new_x - 1, new_y, 1]) if new_x == x
            @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
            @walls.push([new_x, new_y - 1, 3]) if new_y == y
            @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
          end
        end
        @next_feature = 1
      end
      
      def dig_corridor(x, y, direction)
        j = 0
        width = rand(@rmiw) + @rmaw - @rmiw + 1
        height = 0
        for i in 0...width
          case direction
          when 0; new_x = x + j; new_y = y + i
          when 1; new_x = x - i; new_y = y + j
          when 2; new_x = x + i; new_y = y + j  
          when 3; new_x = x + j; new_y = y - i 
          end
          @map.data[new_x, new_y, 0] = @floor_tile
          @floor.push([new_x, new_y]) 
          @walls.push([new_x - 1, new_y, 1]) if new_x == x
          @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
          @walls.push([new_x, new_y - 1, 3]) if new_y == y
          @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
        end
        case direction
        when 0; @next_wall = [x + height, y + width, 0]
        when 1; @next_wall = [x - width, y + height, 1]
        when 2; @next_wall = [x + width, y + height, 2]
        when 3; @next_wall = [x + height, y - width, 3]
        end
        @next_feature = 0
      end
      
      def choose_next_wall; @next_wall = @walls[rand(@walls.size)]; end
      
      def make_new_feature
        direction = rand(4)
        @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
        return if not @can_make
        @walls.delete(@next_wall)
        dig_corridor(@next_wall[0], @next_wall[1], @next_wall[2])
        @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
        dig_room(@next_wall[0], @next_wall[1], @next_wall[2]) if @can_make
        @next_feature = 1
      end
      
      def scan_area(x, y, direction)
        case @next_feature
        when 0
          for i in 0..@rmaw + 1; for j in 0..@rmah + 1
            case direction
            when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
            when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
            when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
            when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
            end
          end; end
        when 1
          for i in 0..@rmaw + 1; for j in -2..2
            case direction
            when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
            when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
            when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
            when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
            end
          end; end
        end
        return true
      end
      
      def refine_tilemap
        for point in @floor
          next if passable?(point[0], point[1] - 1)
          if passable?(point[0], point[1] - 2)
            @map.data[point[0], point[1] - 1, 0] = @floor_tile
          else
            @map.data[point[0], point[1] - 1, 0] = @wall2_tile
          end
        end
        for i in 0...width; for j in 0...height
          next if @map.data[i, j, 0] == @floor_tile 
          type = @map.data[i, j, 0] == @wall2_tile ? 1 : 0
          @map.data[i, j, 0] = rdg_tilemap_id(i, j, type) 
        end; end
        return if not @black_outline
        for i in 0...width; for j in 0...height
          next if @floor.include?([i, j])
          if (@map.data[i, j, 0] - 2048) % 48 == 0 
            @map.data[i, j, 0] = 0
          end
        end; end
      end
      
      def rdg_tilemap_id(x, y, type)
        data = @map.data
        base = @map.data[x, y, 0]
        return base if x == 0 or x == width - 1 or y == 0 or y == width - 1
        case type
        when 0
          count = 0
          count += 1 if (data[x - 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
          count += 2 if (data[x, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
          count += 4 if (data[x + 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
          count += 8 if (data[x, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
          id = case count 
          when 0 then check_corners(x, y, base)
          when 1 then 16 + ((check_corners(x, y, base, [2, 4])) / 2)
          when 2 then 20 + ((check_corners(x, y, base, [4, 8])) / 4)
          when 3 then 34 + ((check_corners(x, y, base, [4])) / 4)
          when 4 then 24 + ([0,8,1,9].index(check_corners(x, y, base, [1, 8])))
          when 5 then 32
          when 6 then 36 + ((check_corners(x, y, base, [8])) / 8)
          when 7 then 42
          when 8 then 28 + check_corners(x, y, base, [1, 2])
          when 9 then 40 + ((check_corners(x, y, base, [2])) / 2)
          when 10 then 33
          when 11 then 43
          when 12 then 38 + check_corners(x, y, base, [1])
          else
            31 + count
          end
        when 1
          count = 0
          count += 1 if passable?(x - 1, y)
          count += 4 if passable?(x + 1, y)
          id = count + 10
        end
        return base + id
      end
    
      def check_corners(x, y, base, corners = [1, 2, 4, 8])
        count = 0
        data = @map.data
        count += 1 if corners.include?(1) and (data[x - 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
        count += 2 if corners.include?(2) and (data[x + 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
        count += 4 if corners.include?(4) and (data[x + 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
        count += 8 if corners.include?(8) and (data[x - 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
        return count
      end
      
    end
    __________________