Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Class to produce random map layouts
- # based on this code: http://www.roguebasin.com/index.php?title=Dungeon_builder_written_in_Python
- # Original author: Steve Wallace
- # Ruby-version author: DeadElf79
- # e-mail me deadelf@gmail.com if you found error
- class DungeonMap
- # Initialize
- #
- def initialize
- @room_list=[]
- @cor_list=[]
- end
- # Generate random layout of rooms, corridors and
- # other features
- # This method can be modified to accept arguments for
- # values of failed, and percentile of features.
- #
- def make_map(xs, ys, fail, b1, mrooms)
- # Create first room
- @xsize = xs
- @ysize = ys
- # initialize map to all walls
- @mapArr= []
- @ysize.times{
- @mapArr<<Array.new(@xsize,1)
- }
- w,l,t=make_room
- while @room_list.size==0
- x=rand(@xsize-1-w)+1
- y=rand(@ysize-1-l)+1
- p=place_room(l,w,x,y,@xsize,@ysize,6,0)
- end
- failed=0
- while failed<fail # The lower the value that failed<, the smaller the dungeon
- choose_room=rand(@room_list.size)
- ex,ey,ex2,ey2,et=make_exit(choose_room)
- feature=rand(100)
- if feature<b1 # Begin feature choosing (more features to be added here)
- w,l,t=make_corridor
- else
- w,l,t=make_room
- end
- room_done=place_room(l,w,ex2,ey2,@xsize,@ysize,t,et)
- case room_done
- when 0 # If placement failed increase possibility map is full
- failed+=1
- when 2 # If Possibility of linking rooms
- if @mapArr[ey2][ex2]==0
- if rand(100)<7
- make_portal(ex,ey)
- end
- failed+=1
- end
- else # Otherwise, link up the 2 rooms
- make_portal(ex,ey)
- failed=0
- if t<5
- tc=[@room_list.size-1,ex2,ey2,t]
- @cor_list<<tc
- join_corridor(@room_list.size-1,ex2,ey2,t,50)
- end
- end
- failed=fail if @room_list.size==mrooms
- end
- final_joins
- @mapArr
- end
- # Randomly produce room size
- #
- def make_room
- rtype=5
- rwide=rand(8)+3
- rlong=rand(8)+3
- return rtype,rwide,rlong
- end
- # Randomly produce corridor length and heading
- #
- def make_corridor
- clength=rand(18)+3
- heading=rand(3)
- case heading
- when 0 # North
- wd=1
- lg=-clength
- when 1 # East
- wd=clength
- lg=1
- when 2 # South
- wd=1
- lg=clength
- when 3 # West
- wd=-clength
- lg=1
- end
- return wd,lg,heading
- end
- # Place feature if enough space and return:
- # 0 - if no space
- # 1 - add room
- # 2 - linking rooms
- def place_room(ll,ww,xposs,yposs,xsize,ysize,rty,ext)
- # Arrange for heading
- xpos=xposs
- ypos=yposs
- if ll<0 then
- ypos+=ll+1
- ll=ll.abs
- end
- if ww<0 then
- xpos+=ww+1
- ww=ww.abs
- end
- # Make offset if type is room
- if rty==5 then
- if ext==(0||2) then
- offset=rand(ww)
- xpos-=offset
- else
- offset=rand(ll)
- ypos-=offset
- end
- end
- # Then check if there is space
- if (ww+xpos+1>xsize-1)||(ll+ypos+1>ysize)
- return 0
- elsif xpos<1 or ypos<1
- return 0
- else
- ll.times{|j|
- ww.times{|k|
- return 2 if @mapArr[(ypos-1)+j][(xpos-1)+k]!=1
- }
- }
- end
- # If there is space, add to list of rooms
- temp=[ll,ww,xpos,ypos]
- @room_list<<temp
- (ll+2).times{|j|# Then build walls
- (ww+2).times{|k|
- @mapArr[(ypos-1)+j][(xpos-1)+k]=2
- }
- }
- ll.times{|j|# Then build floor
- ww.times{|k|
- @mapArr[ypos+j][xpos+k]=0
- }
- }
- return 1
- end
- # Pick random wall and random point along that wall
- #
- def make_exit(rn)
- room=@room_list[rn]
- rx,ry,rx2,ry2,rw=0,0,0,0,0
- loop do
- rw=rand(3)
- case rw
- when 0 # North wall
- rx=rand(room[1])+room[2]
- ry=room[3]-1
- rx2=rx
- ry2=ry-1
- when 1 # East wall
- ry=rand(room[0])+room[3]
- rx=room[2]+room[1]
- rx2=rx+1
- ry2=ry
- when 2 # South wall
- rx=rand(room[1])+room[2]
- ry=room[3]+room[0]
- rx2=rx
- ry2=ry+1
- when 3 # West wall
- ry=rand(room[0])+room[3]
- rx=room[2]-1
- rx2=rx-1
- ry2=ry
- end
- break if @mapArr[ry][rx]==2 # If space is a wall, exit
- end
- return rx,ry,rx2,ry2,rw
- end
- # Create doors in walls
- #
- def make_portal(px,py)
- ptype=rand(100)
- if ptype>90 # Secret door
- @mapArr[py][px]=5
- elsif ptype>75 # Closed door
- @mapArr[py][px]=4
- elsif ptype>40 # Open door
- @mapArr[py][px]=3
- else # Hole in the wall door
- @mapArr[py][px]=0
- end
- end
- # Check corridor endpoint and make an exit if it links to another room
- #
- def join_corridor(cno,xp,yp,ed,psb)
- cArea=@room_list[cno]
- if xp!=cArea[2] or yp!=cArea[3] # Find the corridor endpoint
- endx=xp-(cArea[1]-1)
- endy=yp-(cArea[0]-1)
- else
- endx=xp+(cArea[1]-1)
- endy=xp+(cArea[0]-1)
- end
- check_exit=[]
- case ed
- when 0 # North corridor
- if endx>1
- coords=[endx-2,endy,endx-1,endy]
- check_exit<<coords
- end
- if endy>1
- coords=[endx,endy-2,endx,endy-1]
- check_exit<<coords
- end
- if endx<@xsize-2
- coords=[endx+2,endy,endx+1,endy]
- check_exit<<coords
- end
- when 1 # East corridor
- if endy>1
- coords=[endx,endy-2,endx,endy-1]
- check_exit<<coords
- end
- if endx<@xsize-2
- coords=[endx+2,endy,endx+1,endy]
- check_exit<<coords
- end
- if endy<@ysize-2
- coords=[endx,endy+2,endx,endy+1]
- check_exit<<coords
- end
- when 2 # South corridor
- if endx<@xsize-2
- coords=[endx+2,endy,endx+1,endy]
- check_exit<<coords
- end
- if endy<@ysize-2
- coords=[endx,endy+2,endx,endy+1]
- check_exit<<coords
- end
- if endx>1
- coords=[endx-2,endy,endx-1,endy]
- check_exit<<coords
- end
- when 3 # West corridor
- if endx>1
- coords=[endx-2,endy,endx-1,endy]
- check_exit<<coords
- end
- if endy>1
- coords=[endx,endy-2,endx,endy-1]
- check_exit<<coords
- end
- if endy<@ysize-2
- coords=[endx,endy+2,endx,endy+1]
- check_exit<<coords
- end
- end
- for xxx,yyy,xxx1,yyy1 in check_exit # Loop through possible exits
- if @mapArr[yyy][xxx]==0 # If joins to a room
- if rand(100)<psb # Possibility of linking rooms
- make_portal(xxx1,yyy1)
- end
- end
- end
- end
- # Final stage, loop through all the corridors to see if any can be joined to other rooms
- #
- def final_joins
- @cor_list.each{|x|
- join_corridor(x[0],x[1],x[2],x[3],10)
- }
- end
- end
- # TEST ZONE
- begin
- MAPWIDTH=40
- MAPHEIGHT=25
- FAILS=110
- B1=20
- MAPROOMS=20
- dung=DungeonMap.new
- map=dung.make_map(MAPWIDTH,MAPHEIGHT,FAILS,B1,MAPROOMS)
- tilemap=[]
- MAPHEIGHT.times{
- tilemap<<Array.new(MAPWIDTH,0)
- }
- MAPHEIGHT.times{|y|
- MAPWIDTH.times{|x|
- case map[y][x]
- when 0
- tilemap[y][x]='.'
- when 1
- tilemap[y][x]=' '
- when 2
- tilemap[y][x]='#'
- when 3,4,5
- tilemap[y][x]='='
- end
- }
- }
- MAPHEIGHT.times{|y|
- puts tilemap[y].to_s
- }
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement