160 lines
4.1 KiB
Lua
160 lines
4.1 KiB
Lua
-- Arguments
|
|
-- map_data: The map data source
|
|
-- chunk: The chunk coordinate conversion API
|
|
local map_data, chunk = ...;
|
|
|
|
-- The map 'class'
|
|
local Map = {};
|
|
Map.__index = Map;
|
|
|
|
for _,loaded_map in ipairs(map_data.maps) do
|
|
setmetatable(loaded_map, Map);
|
|
end
|
|
|
|
-- Resize this map
|
|
--
|
|
-- w: The new width
|
|
-- h: The new height
|
|
function Map.resize(self, w, h)
|
|
if w >= self.w and h >= self.h then
|
|
self.w = w;
|
|
self.h = h;
|
|
-- FIXME: Is this really correct? Seems questionable.
|
|
end
|
|
end
|
|
|
|
|
|
-- Fill in a region of this map
|
|
--
|
|
-- x: The x position, in map coordinates
|
|
-- z: The z position, in map coordinates
|
|
-- w: The width, in map coordinates
|
|
-- h: The height, in map coordinates
|
|
function Map.fill_area(self, x, z, w, h)
|
|
for i = math.max(x, self.x),math.min(x + w - 1, self.x + self.w),1 do
|
|
for j = math.max(z, self.z),math.min(z + h - 1, self.z + self.h),1 do
|
|
self.fill[(i - self.x) + ((j - self.z) * self.w)] = self.detail;
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Set the marker at the given position
|
|
--
|
|
-- x: The x position, in map coordinates
|
|
-- z: The z position, in map coordinates
|
|
-- marker: The marker ID to set, or nil to unset
|
|
function Map.set_marker(self, x, z, marker)
|
|
if x < self.x or x > self.x + self.w or z < self.z or z > self.z + self.h then
|
|
return;
|
|
end
|
|
|
|
if not self.markers[x] then
|
|
self.markers[x] = {
|
|
[z] = marker,
|
|
};
|
|
else
|
|
self.markers[x][z] = marker;
|
|
end
|
|
end
|
|
|
|
-- Get the marker at the given position
|
|
--
|
|
-- x: The x position, in map coordinates
|
|
-- z: The z position, in map coordinates
|
|
--
|
|
-- Returns a marker id
|
|
function Map.get_marker(self, x, z)
|
|
if x < self.x or x > self.x + self.w or z < self.z or z > self.z + self.h or not self.markers[x] then
|
|
return nil;
|
|
end
|
|
|
|
return self.markers[x][z];
|
|
end
|
|
|
|
-- Fill in the local area of a map around a position
|
|
--
|
|
-- id: A map ID
|
|
-- x: The x position, in world coordinates
|
|
-- z: The z position, in world coordinates
|
|
function Map.fill_local(self, x, z)
|
|
x, z = self:to_coordinates(x, z);
|
|
|
|
-- TODO: Adjust size to match map scale
|
|
if x >= self.x - 2 and x <= self.x + self.w + 1 and z >= self.z - 2 and z <= self.z + self.h + 1 then
|
|
self:fill_area(x - 2, z - 2, 5, 5);
|
|
end
|
|
end
|
|
|
|
-- Convert a position in world coordinates to the given map's coordinate system
|
|
--
|
|
-- x: The x position, in world coordinates
|
|
-- z: The z position, in world coordinates
|
|
--
|
|
-- Returns The converted x and z coordinates
|
|
function Map.to_coordinates(self, x, z)
|
|
if self.scale == 0 then
|
|
return chunk.to(x), chunk.to(z);
|
|
end
|
|
|
|
return math.floor(chunk.to(x) / self.scale + 0.5), math.floor(chunk.to(z) / self.scale + 0.5);
|
|
end
|
|
|
|
-- Check if the given position on this map is filled
|
|
--
|
|
-- x: The x position, in map coordinates
|
|
-- z: The z position, in map coordinates
|
|
function Map.is_filled(self, x, z)
|
|
return self.fill[(x - self.x) + ((z - self.z) * self.w)] ~= nil;
|
|
end
|
|
|
|
-- The Map API
|
|
local maps = {
|
|
-- Create a new map object with the given parameters
|
|
--
|
|
-- x: The x position, in map coordinates
|
|
-- z: The z position, in map coordinates
|
|
-- w: The width, in map coordinates
|
|
-- h: The height, in map coordinates
|
|
-- filled: Whether or not the map is pre-filled
|
|
-- detail: The detail level
|
|
-- scale: The scale factor
|
|
--
|
|
-- Returns the new map's id
|
|
create = function(x, z, w, h, filled, detail, scale)
|
|
local id = map_data.next_map_id;
|
|
|
|
local map = {
|
|
id = id,
|
|
x = x,
|
|
z = z,
|
|
w = w,
|
|
h = h,
|
|
detail = detail,
|
|
scale = scale,
|
|
fill = {},
|
|
markers = {},
|
|
};
|
|
setmetatable(map, Map);
|
|
|
|
map_data.maps[id] = map;
|
|
if filled then
|
|
map:fill(map, x, z, w, h);
|
|
end
|
|
|
|
map_data.next_map_id = map_data.next_map_id + 1;
|
|
|
|
return id;
|
|
end,
|
|
|
|
-- Get the map objwct assigned to the given id
|
|
--
|
|
-- id: The map id
|
|
--
|
|
-- Returns a map object, or nil if the id is invalid
|
|
get = function(id)
|
|
return map_data.maps[id];
|
|
end,
|
|
}
|
|
|
|
return maps;
|