-- draw our map starting at room: uid
function real_draw (uid)
if not uid then
maperror "Cannot draw map right now, I don't know where you are - try: LOOK"
return
end -- if
if current_room and current_room ~= uid then
changed_room (uid)
end -- if
current_room = uid -- remember where we are
-- timing
local start_time = utils.timer ()
-- start with initial room
rooms = { [uid] = get_room (uid) }
-- lookup current room
local room = rooms [uid]
room = room or { name = "<Unknown room>", area = "<Unknown area>" }
last_visited [uid] = os.time ()
current_area = room.area
-- we are recreating the window so any mouse-over is not valid any more
if WindowInfo (win, 19) and WindowInfo (win, 19) ~= "" then
if type (room_cancelmouseover) == "function" then
room_cancelmouseover (WindowInfo (win, 19), 0) -- cancelled mouse over
end -- if
end -- have a hotspot
WindowDeleteAllHotspots (win)
WindowCreate (win,
windowinfo.window_left,
windowinfo.window_top,
config.WINDOW.width,
config.WINDOW.height,
windowinfo.window_mode, -- top right
windowinfo.window_flags,
config.BACKGROUND_COLOUR.colour)
-- let them move it around
movewindow.add_drag_handler (win, 0, 0, 0, font_height + 4)
-- for zooming
WindowAddHotspot(win,
"zzz_zoom",
0, 0, 0, 0,
"", "", "", "", "",
"", -- hint
miniwin.cursor_arrow, 0)
WindowScrollwheelHandler (win, "zzz_zoom", "mapper.zoom_map")
-- 3D box around whole thing
draw_3d_box (win, 0, 0, config.WINDOW.width, config.WINDOW.height)
-- make sure window visible
WindowShow (win, not hidden)
-- set up for initial room, in middle
drawn, drawn_coords, rooms_to_be_drawn, speedwalks, plan_to_draw, area_exits = {}, {}, {}, {}, {}, {}
depth = 0
-- insert initial room
table.insert (rooms_to_be_drawn, add_another_room (uid, {}, config.WINDOW.width / 2, config.WINDOW.height / 2))
while #rooms_to_be_drawn > 0 and depth < config.SCAN.depth do
local old_generation = rooms_to_be_drawn
rooms_to_be_drawn = {} -- new generation
for i, part in ipairs (old_generation) do
draw_room (part.uid, part.path, part.x, part.y)
end -- for each existing room
depth = depth + 1
Redraw ()
coroutine.yield () -- stop for a moment
end -- while all rooms_to_be_drawn
for area, zone_exit in pairs (area_exits) do
draw_zone_exit (zone_exit)
end -- for
local room_name = room.name
local name_width = WindowTextWidth (win, FONT_ID, room_name, true)
local add_dots = false
-- truncate name if too long
while name_width > (config.WINDOW.width - 10) do
-- get rid of last word
local s = string.match (" " .. room_name .. "...", "(%s%S*)$")
if not s or #s == 0 then break end
room_name = room_name:sub (1, - (#s - 2)) -- except the last 3 dots but add the space
name_width = WindowTextWidth (win, FONT_ID, room_name .. " ...", true)
add_dots = true
end -- while
if add_dots then
room_name = room_name .. " ..."
end -- if
-- room name
draw_text_box (win, FONT_ID,
(config.WINDOW.width - WindowTextWidth (win, FONT_ID, room_name, true)) / 2, -- left
3, -- top
room_name, true, -- what to draw, utf8
config.ROOM_NAME_TEXT.colour, -- text colour
config.ROOM_NAME_FILL.colour, -- fill colour
config.ROOM_NAME_BORDER.colour) -- border colour
-- area name
local areaname = room.area
if areaname then
draw_text_box (win, FONT_ID,
(config.WINDOW.width - WindowTextWidth (win, FONT_ID, areaname, true)) / 2, -- left
config.WINDOW.height - 6 - font_height, -- top
areaname, true, -- what to draw, utf8
config.AREA_NAME_TEXT.colour, -- text colour
config.AREA_NAME_FILL.colour, -- fill colour
config.AREA_NAME_BORDER.colour) -- border colour
end -- if area known
-- configure?
if draw_configure_box then
draw_configuration ()
else
local x = 5
local y = config.WINDOW.height - 6 - font_height
local width = draw_text_box (win, FONT_ID,
x, -- left
y, -- top (ie. at bottom)
"*", true, -- what to draw, utf8
config.AREA_NAME_TEXT.colour, -- text colour
config.AREA_NAME_FILL.colour, -- fill colour
config.AREA_NAME_BORDER.colour) -- border colour
WindowAddHotspot(win, "<configure>",
x, y, x + width, y + font_height, -- rectangle
"", -- mouseover
"", -- cancelmouseover
"", -- mousedown
"", -- cancelmousedown
"mapper.mouseup_configure", -- mouseup
"Click to configure map",
miniwin.cursor_hand, 0) -- hand cursor
end -- if
if type (show_help) == "function" then
local x = config.WINDOW.width - WindowTextWidth (win, FONT_ID, "?", true) - 5
local y = config.WINDOW.height - 6 - font_height
local width = draw_text_box (win, FONT_ID,
x, -- left
y, -- top (ie. at bottom)
"?", true, -- what to draw, utf8
config.AREA_NAME_TEXT.colour, -- text colour
config.AREA_NAME_FILL.colour, -- fill colour
config.AREA_NAME_BORDER.colour) -- border colour
WindowAddHotspot(win, "<help>",
x, y, x + width, y + font_height, -- rectangle
"", -- mouseover
"", -- cancelmouseover
"", -- mousedown
"", -- cancelmousedown
"mapper.show_help", -- mouseup
"Click for help",
miniwin.cursor_hand, 0) -- hand cursor
end -- if
-- 3D box around whole thing
draw_3d_box (win, 0, 0, config.WINDOW.width, config.WINDOW.height)
-- make sure window visible
WindowShow (win, not hidden)
last_drawn = uid -- last room number we drew (for zooming)
local end_time = utils.timer ()
-- timing stuff
if timing then
local count= 0
for k in pairs (drawn) do
count = count + 1
end
print (string.format ("Time to draw %i rooms = %0.3f seconds, search depth = %i", count, end_time - start_time, depth))
total_times_drawn = total_times_drawn + 1
total_time_taken = total_time_taken + end_time - start_time
print (string.format ("Total times map drawn = %i, average time to draw = %0.3f seconds",
total_times_drawn,
total_time_taken / total_times_drawn))
end -- if
thread = nil -- don't need to call coroutine any more
end -- real_draw
function draw (uid)
thread = coroutine.create (real_draw) -- thread will run function real_draw
assert (coroutine.resume (thread, uid)) -- start thread, passing argument uid
end -- draw
function keep_drawing ()
if thread then
coroutine.resume (thread)
end -- if
end -- keep_drawing