Guest User

dungeon_gen.vx

a guest
Dec 8th, 2015
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.30 KB | None | 0 0
  1. #===============================================================================
  2. # Roguelike Random Dungeon Generator
  3. #-------------------------------------------------------------------------------
  4. # Version: 2.0a
  5. # Author: cozziekuns (rmrk)
  6. # Last Date Updated: 4/11/2011
  7. #===============================================================================
  8. # Description:
  9. #-------------------------------------------------------------------------------
  10. # A random dungeon generator akin to that of games like Rogue or Pokemon Mystery
  11. # Dungeon.
  12. #===============================================================================
  13. # Updates
  14. # ------------------------------------------------------------------------------
  15. # o 16/07/2011 - Started Script
  16. # o 17/07/2011 - Updated Script to support black outlines and some autotile
  17. # features
  18. # o 15/09/2011 - Bugfix.
  19. # o 17/09/2011 - Major overhaul of the entire script. Now has fully functional
  20. # autotile support, and a much faster algorithm that can create a
  21. # 500 * 500 tile map with 1000 features in less than 10 seconds.
  22. #===============================================================================
  23. # To-do List
  24. #-------------------------------------------------------------------------------
  25. # o Nothing! Suggest some features.
  26. #===============================================================================
  27. # Instructions
  28. #-------------------------------------------------------------------------------
  29. # Copy and paste this script above ? Main Process but below ? Materials, and
  30. # edit the modules to your liking. Some difficult modules have links to the
  31. # instructions.
  32. #===============================================================================
  33. # Maps
  34. #-------------------------------------------------------------------------------
  35. # Start editing at:
  36. # case id
  37. # when [id] - Replace [id] with your map id.
  38. # ROOM_MIN_WIDTH : Minimum width for a single "Room"
  39. # ROOM_MAX_WIDTH : Maximum width for a single "Room"
  40. # ROOM_MIN_HEIGHT : Minimum height for a single "Room"
  41. # ROOM_MAX_HEIGHT : Maximum height for a single "Room"
  42. # FEATURES : How many features you want to fit in the map
  43. # WALL_TILE : Tile of the wall
  44. # FLOOR_TILE : Tile of the floor
  45. # BLACK_OUTLINE : Do you want a black outline surrounding your random
  46. # dungeon (slow).
  47. # end
  48. #===============================================================================
  49.  
  50. module COZZIEKUNS
  51.  
  52. module RDG
  53.  
  54. def self.map_settings(id)
  55. case id
  56. when 1
  57. room_min_width = 3
  58. room_max_width = 6
  59. room_min_height = 3
  60. room_max_height = 6
  61. features = 200
  62. wall_tile = 0
  63. floor_tile = 16
  64. black_outline = false
  65. when 2
  66. room_min_width = 4
  67. room_max_width = 8
  68. room_min_height = 4
  69. room_max_height = 8
  70. features = 75
  71. wall_tile = 6
  72. floor_tile = 52
  73. black_outline = false
  74. end
  75. return [room_min_width, room_max_width, room_min_height, room_max_height,
  76. features, wall_tile, floor_tile, black_outline].compact
  77. end
  78.  
  79. end
  80.  
  81. end
  82.  
  83. #==============================================================================
  84. # ** Game_Map
  85. #==============================================================================
  86.  
  87. class Game_Map
  88.  
  89. alias coz_rdg_gm_setup setup
  90. def setup(*args)
  91. coz_rdg_gm_setup(*args)
  92. create_dungeon if not COZZIEKUNS::RDG.map_settings(@map_id).empty?
  93. end
  94.  
  95. def create_dungeon
  96. set_variables
  97. fill_wall_tiles
  98. dig_random_room
  99. for i in 0...@features
  100. count = 0
  101. loop do
  102. count += 1
  103. choose_next_wall
  104. make_new_feature
  105. break if @can_make or count == 5
  106. end
  107. end
  108. refine_tilemap
  109. set_player_and_events
  110. end
  111.  
  112. def set_variables
  113. settings = COZZIEKUNS::RDG.map_settings(@map_id)
  114. @rmiw = settings[0]
  115. @rmaw = settings[1]
  116. @rmih = settings[2]
  117. @rmah = settings[3]
  118. @features = settings[4]
  119. @walls = []
  120. @floor = []
  121. @next_wall = []
  122. @wall_tile = (settings[5] + 80) * 48 + 2048
  123. @wall2_tile = (settings[5] + 88) * 48 + 2048
  124. @floor_tile = (settings[6] + 128) + 1408
  125. @black_outline = settings[7]
  126. @next_feature = 0
  127. @can_make = false
  128. @player_transfered = false
  129. end
  130.  
  131. def set_player_and_events
  132. for event in $game_map.events.values + [$game_player]
  133. loop do
  134. ax = @floor[rand(@floor.size)][0]
  135. ay = @floor[rand(@floor.size)][1]
  136. if passable_in_area?(ax - 1, ay - 1, event)
  137. event.moveto(ax, ay)
  138. break
  139. end
  140. end
  141. end
  142. end
  143.  
  144. alias coz_rdg_gm_update update
  145. def update
  146. coz_rdg_gm_update
  147. unless @player_transfered or COZZIEKUNS::RDG.map_settings(@map_id).empty?
  148. @player_transfered = true
  149. set_player_and_events
  150. end
  151. end
  152.  
  153. def passable_in_area?(x, y, char, width = 3, height = 3)
  154. for i in x...x + width; for j in y...y + height
  155. return false if not char.passable?(i, j)
  156. end; end
  157. return true
  158. end
  159.  
  160. def fill_wall_tiles
  161. for i in 0...width; for j in 0...height
  162. @map.data[i, j, 0] = @wall_tile
  163. end; end
  164. end
  165.  
  166. def dig_random_room
  167. x = [rand(width) + 1, width - @rmaw - 1].min
  168. y = [rand(height) + 1, height - @rmah - 1].min
  169. dig_room(x, y)
  170. end
  171.  
  172. def dig_room(x, y, direction = 2)
  173. width = rand(@rmiw) + @rmaw - @rmiw + 1
  174. height = rand(@rmih) + @rmah - @rmih + 1
  175. for i in 0...width
  176. for j in 0...height
  177. case direction
  178. when 0; new_x = x + j; new_y = y + i
  179. when 1; new_x = x - i; new_y = y + j
  180. when 2; new_x = x + i; new_y = y + j
  181. when 3; new_x = x + j; new_y = y - i
  182. end
  183. @map.data[new_x, new_y, 0] = @floor_tile
  184. @floor.push([new_x, new_y])
  185. @walls.push([new_x - 1, new_y, 1]) if new_x == x
  186. @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
  187. @walls.push([new_x, new_y - 1, 3]) if new_y == y
  188. @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
  189. end
  190. end
  191. @next_feature = 1
  192. end
  193.  
  194. def dig_corridor(x, y, direction)
  195. j = 0
  196. width = rand(@rmiw) + @rmaw - @rmiw + 1
  197. height = 0
  198. for i in 0...width
  199. case direction
  200. when 0; new_x = x + j; new_y = y + i
  201. when 1; new_x = x - i; new_y = y + j
  202. when 2; new_x = x + i; new_y = y + j
  203. when 3; new_x = x + j; new_y = y - i
  204. end
  205. @map.data[new_x, new_y, 0] = @floor_tile
  206. @floor.push([new_x, new_y])
  207. @walls.push([new_x - 1, new_y, 1]) if new_x == x
  208. @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
  209. @walls.push([new_x, new_y - 1, 3]) if new_y == y
  210. @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
  211. end
  212. case direction
  213. when 0; @next_wall = [x + height, y + width, 0]
  214. when 1; @next_wall = [x - width, y + height, 1]
  215. when 2; @next_wall = [x + width, y + height, 2]
  216. when 3; @next_wall = [x + height, y - width, 3]
  217. end
  218. @next_feature = 0
  219. end
  220.  
  221. def choose_next_wall; @next_wall = @walls[rand(@walls.size)]; end
  222.  
  223. def make_new_feature
  224. direction = rand(4)
  225. @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
  226. return if not @can_make
  227. @walls.delete(@next_wall)
  228. dig_corridor(@next_wall[0], @next_wall[1], @next_wall[2])
  229. @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
  230. dig_room(@next_wall[0], @next_wall[1], @next_wall[2]) if @can_make
  231. @next_feature = 1
  232. end
  233.  
  234. def scan_area(x, y, direction)
  235. case @next_feature
  236. when 0
  237. for i in 0..@rmaw + 1; for j in 0..@rmah + 1
  238. case direction
  239. when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
  240. when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
  241. when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
  242. when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
  243. end
  244. end; end
  245. when 1
  246. for i in 0..@rmaw + 1; for j in -2..2
  247. case direction
  248. when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
  249. when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
  250. when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
  251. when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
  252. end
  253. end; end
  254. end
  255. return true
  256. end
  257.  
  258. def refine_tilemap
  259. for point in @floor
  260. next if passable?(point[0], point[1] - 1)
  261. if passable?(point[0], point[1] - 2)
  262. @map.data[point[0], point[1] - 1, 0] = @floor_tile
  263. else
  264. @map.data[point[0], point[1] - 1, 0] = @wall2_tile
  265. end
  266. end
  267. for i in 0...width; for j in 0...height
  268. next if @map.data[i, j, 0] == @floor_tile
  269. type = @map.data[i, j, 0] == @wall2_tile ? 1 : 0
  270. @map.data[i, j, 0] = rdg_tilemap_id(i, j, type)
  271. end; end
  272. return if not @black_outline
  273. for i in 0...width; for j in 0...height
  274. next if @floor.include?([i, j])
  275. if (@map.data[i, j, 0] - 2048) % 48 == 0
  276. @map.data[i, j, 0] = 0
  277. end
  278. end; end
  279. end
  280.  
  281. def rdg_tilemap_id(x, y, type)
  282. data = @map.data
  283. base = @map.data[x, y, 0]
  284. return base if x == 0 or x == width - 1 or y == 0 or y == width - 1
  285. case type
  286. when 0
  287. count = 0
  288. count += 1 if (data[x - 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  289. count += 2 if (data[x, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  290. count += 4 if (data[x + 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  291. count += 8 if (data[x, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  292. id = case count
  293. when 0 then check_corners(x, y, base)
  294. when 1 then 16 + ((check_corners(x, y, base, [2, 4])) / 2)
  295. when 2 then 20 + ((check_corners(x, y, base, [4, 8])) / 4)
  296. when 3 then 34 + ((check_corners(x, y, base, [4])) / 4)
  297. when 4 then 24 + ([0,8,1,9].index(check_corners(x, y, base, [1, 8])))
  298. when 5 then 32
  299. when 6 then 36 + ((check_corners(x, y, base, [8])) / 8)
  300. when 7 then 42
  301. when 8 then 28 + check_corners(x, y, base, [1, 2])
  302. when 9 then 40 + ((check_corners(x, y, base, [2])) / 2)
  303. when 10 then 33
  304. when 11 then 43
  305. when 12 then 38 + check_corners(x, y, base, [1])
  306. else
  307. 31 + count
  308. end
  309. when 1
  310. count = 0
  311. count += 1 if passable?(x - 1, y)
  312. count += 4 if passable?(x + 1, y)
  313. id = count + 10
  314. end
  315. return base + id
  316. end
  317.  
  318. def check_corners(x, y, base, corners = [1, 2, 4, 8])
  319. count = 0
  320. data = @map.data
  321. count += 1 if corners.include?(1) and (data[x - 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  322. count += 2 if corners.include?(2) and (data[x + 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  323. count += 4 if corners.include?(4) and (data[x + 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  324. count += 8 if corners.include?(8) and (data[x - 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
  325. return count
  326. end
  327.  
  328. end
Advertisement
Add Comment
Please, Sign In to add comment