mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Ensured random dungeons place large events properly
This commit is contained in:
@@ -376,6 +376,7 @@ module RandomDungeon
|
|||||||
@usable_width -= 1 if @usable_width.odd?
|
@usable_width -= 1 if @usable_width.odd?
|
||||||
@usable_height -= 1 if @usable_height.odd?
|
@usable_height -= 1 if @usable_height.odd?
|
||||||
end
|
end
|
||||||
|
@room_rects = []
|
||||||
@map_data = DungeonLayout.new(@width, @height)
|
@map_data = DungeonLayout.new(@width, @height)
|
||||||
@need_redraw = false
|
@need_redraw = false
|
||||||
end
|
end
|
||||||
@@ -804,6 +805,7 @@ module RandomDungeon
|
|||||||
end
|
end
|
||||||
x = x.clamp(@buffer_x, @usable_width - @buffer_x - width)
|
x = x.clamp(@buffer_x, @usable_width - @buffer_x - width)
|
||||||
y = y.clamp(@buffer_y, @usable_height - @buffer_y - height)
|
y = y.clamp(@buffer_y, @usable_height - @buffer_y - height)
|
||||||
|
@room_rects.push([x, y, width, height])
|
||||||
paint_ground_rect(x, y, width, height, :room)
|
paint_ground_rect(x, y, width, height, :room)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1002,19 +1004,36 @@ module RandomDungeon
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a random room tile in the dungeon that isn't too close to a
|
# Returns a random room tile a random room where an event of the given size
|
||||||
# corridor (to avoid blocking a room's entrance).
|
# can be placed. Events cannot be placed adjacent to or overlapping each
|
||||||
def get_random_room_tile(occupied_tiles)
|
# other, and can't be placed right next to the wall of a room (to prevent
|
||||||
ar1 = AntiRandom.new(@width)
|
# them blocking a corridor).
|
||||||
ar2 = AntiRandom.new(@height)
|
def get_random_room_tile(occupied_tiles, event_width = 1, event_height = 1)
|
||||||
((occupied_tiles.length + 1) * 1000).times do
|
valid_rooms = @room_rects.clone
|
||||||
x = ar1.get
|
valid_rooms.delete_if { |rect| rect[2] <= event_width + 1 || rect[3] <= event_height + 1 }
|
||||||
y = ar2.get
|
return nil if valid_rooms.empty?
|
||||||
next if !isRoom?(x, y)
|
1000.times do
|
||||||
next if occupied_tiles.any? { |item| (item[0] - x).abs < 2 && (item[1] - y).abs < 2 }
|
room = valid_rooms.sample
|
||||||
ret = [x, y]
|
x = 1 + rand(room[2] - event_width - 1)
|
||||||
occupied_tiles.push(ret)
|
y = 1 + rand(room[3] - event_height - 1)
|
||||||
return ret
|
valid_placement = true
|
||||||
|
event_width.times do |i|
|
||||||
|
event_height.times do |j|
|
||||||
|
if occupied_tiles.any? { |item| (item[0] - (room[0] + x + i)).abs < 2 && (item[1] - (room[1] + y + j)).abs < 2 }
|
||||||
|
valid_placement = false
|
||||||
|
end
|
||||||
|
break if !valid_placement
|
||||||
|
end
|
||||||
|
break if !valid_placement
|
||||||
|
end
|
||||||
|
next if !valid_placement
|
||||||
|
# Found valid placement; use it
|
||||||
|
event_width.times do |i|
|
||||||
|
event_height.times do |j|
|
||||||
|
occupied_tiles.push([room[0] + x + i, room[1] + y + j])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return [room[0] + x, room[1] + y + event_height - 1]
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@@ -1055,20 +1074,34 @@ EventHandlers.add(:on_game_map_setup, :random_dungeon,
|
|||||||
map.height = dungeon.height
|
map.height = dungeon.height
|
||||||
map.data.resize(map.width, map.height, 3)
|
map.data.resize(map.width, map.height, 3)
|
||||||
dungeon.generateMapInPlace(map)
|
dungeon.generateMapInPlace(map)
|
||||||
occupied_tiles = []
|
failed = false
|
||||||
# Reposition the player
|
100.times do |i|
|
||||||
tile = dungeon.get_random_room_tile(occupied_tiles)
|
failed = false
|
||||||
if tile
|
occupied_tiles = []
|
||||||
$game_temp.player_new_x = tile[0]
|
# Reposition events
|
||||||
$game_temp.player_new_y = tile[1]
|
map.events.each_value do |event|
|
||||||
end
|
event_width = 1
|
||||||
# Reposition events
|
event_height = 1
|
||||||
map.events.each_value do |event|
|
if event.name[/size\((\d+),(\d+)\)/i]
|
||||||
tile = dungeon.get_random_room_tile(occupied_tiles)
|
event_width = $~[1].to_i
|
||||||
if tile
|
event_height = $~[2].to_i
|
||||||
|
end
|
||||||
|
tile = dungeon.get_random_room_tile(occupied_tiles, event_width, event_height)
|
||||||
|
failed = true if !tile
|
||||||
|
break if failed
|
||||||
event.x = tile[0]
|
event.x = tile[0]
|
||||||
event.y = tile[1]
|
event.y = tile[1]
|
||||||
end
|
end
|
||||||
|
next if failed
|
||||||
|
# Reposition the player
|
||||||
|
tile = dungeon.get_random_room_tile(occupied_tiles)
|
||||||
|
next if !tile
|
||||||
|
$game_temp.player_new_x = tile[0]
|
||||||
|
$game_temp.player_new_y = tile[1]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if failed
|
||||||
|
raise _INTL("Couldn't place all events and the player in rooms.")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user