From 43406ded7e3c0b25f1c91e35c7ac2972fdc6f3a1 Mon Sep 17 00:00:00 2001 From: Hugues Ross Date: Tue, 9 Jun 2020 20:17:39 -0400 Subject: [PATCH] OO-ifiy map tables --- items.lua | 10 +++---- map_api.lua | 74 +++++++++++++++++++++++++----------------------- map_formspec.lua | 10 ++++++- table.lua | 2 +- 4 files changed, 54 insertions(+), 42 deletions(-) diff --git a/items.lua b/items.lua index bc49dea..c928ac5 100644 --- a/items.lua +++ b/items.lua @@ -125,7 +125,7 @@ local function show_map_id_formspec(id, player_x, player_z, player_name, height_ }; local map = cartographer.get_map(id); - player_x, player_z = cartographer.to_map_coordinates(map, player_x, player_z) + player_x, player_z = map:to_coordinates(player_x, player_z) local formspec, formspec_width, _ = map_formspec.from_map(map, player_x, player_z, height_mode); if #marker_lookup > 0 then local height_button_texture; @@ -147,7 +147,7 @@ local function show_map_id_formspec(id, player_x, player_z, player_name, height_ y = 1, bg = skin.marker_bg, - marker_formspec(cartographer.get_marker(map, player_x, player_z), map.detail, marker_page or 1), + marker_formspec(map:get_marker(player_x, player_z), map.detail, marker_page or 1), }, gui.container { x = formspec_width - 0.01, @@ -245,8 +245,8 @@ minetest.register_on_player_receive_fields(function(player, name, fields) local marker = k:match("marker%-(.+)"); local pos = player:get_pos(); if marker or k == "clear_marker" then - local player_x, player_z = cartographer.to_map_coordinates(map, pos.x, pos.z); - cartographer.set_marker(map, player_x, player_z, marker); + local player_x, player_z = map:to_coordinates(pos.x, pos.z); + map:set_marker(player_x, player_z, marker); cartographer.map_sound("cartographer_write", player); show_map_id_formspec(map.id, pos.x, pos.z, player:get_player_name(), data.page); @@ -404,7 +404,7 @@ function cartographer.resize_map_item(meta, size) local id = meta:get_int("cartographer:map_id"); if id > 0 then local map = cartographer.get_map(id); - cartographer.resize_map(id, size, size); + map:resize(size, size); meta:set_string("description", map_description(id, chunk.from(map.x), chunk.from(map.z), diff --git a/map_api.lua b/map_api.lua index a4c0873..d80c457 100644 --- a/map_api.lua +++ b/map_api.lua @@ -1,5 +1,12 @@ local map_data, chunk, scanner, biome_lookup, marker_lookup = ...; +local Map = {}; +Map.__index = Map; + +for _,loaded_map in ipairs(map_data.maps) do + setmetatable(loaded_map, Map); +end + function cartographer.create_map(x, z, w, h, filled, detail, scale) local id = map_data.next_map_id; @@ -14,10 +21,11 @@ function cartographer.create_map(x, z, w, h, filled, detail, scale) fill = {}, markers = {}, }; + setmetatable(map, Map); map_data.maps[id] = map; if filled then - cartographer.fill(map, x, z, w, h); + map:fill(map, x, z, w, h); end map_data.next_map_id = map_data.next_map_id + 1; @@ -29,46 +37,42 @@ function cartographer.get_map(id) return map_data.maps[id]; end -function cartographer.resize_map(id, w, h) - local map = cartographer.get_map(id); - if map ~= nil and w >= map.w and h >= map.h then - map.w = w; - map.h = h; +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 -function cartographer.fill(map, x, z, w, h) - if map == nil then - return; - end - - for i = math.max(x, map.x),math.min(x + w - 1, map.x + map.w),1 do - for j = math.max(z, map.z),math.min(z + h - 1, map.z + map.h),1 do - map.fill[(i - map.x) + ((j - map.z) * map.w)] = map.detail; +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 -function cartographer.set_marker(map, x, z, marker) - if map == nil or x < map.x or x > map.x + map.w or z < map.z or z > map.z + map.h then +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 map.markers[x] then - map.markers[x] = { + if not self.markers[x] then + self.markers[x] = { [z] = marker, }; else - map.markers[x][z] = marker; + self.markers[x][z] = marker; end end -function cartographer.get_marker(map, x, z) - if map == nil or x < map.x or x > map.x + map.w or z < map.z or z > map.z + map.h or not map.markers[x] then +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 map.markers[x][z]; + return self.markers[x][z]; end -- Fill in the local area of a map around a position @@ -78,26 +82,30 @@ end function cartographer.fill_local(id, x, z) local map = cartographer.get_map(id); - x, z = cartographer.to_map_coordinates(map, x, z); + if not map then + return; + end + + x, z = map:to_coordinates(x, z); -- TODO: Adjust size to match map scale - if map and x >= map.x - 2 and x <= map.x + map.w + 1 and z >= map.z - 2 and z <= map.z + map.h + 1 then - cartographer.fill(map, x - 2, z - 2, 5, 5); + if x >= map.x - 2 and x <= map.x + map.w + 1 and z >= map.z - 2 and z <= map.z + map.h + 1 then + map:fill_area(x - 2, z - 2, 5, 5); end end -- Convert a position in world coordinates to the given map's coordinate system --- map: The map to use as reference, or nil to use the default size (map scale of 1) +-- self: The map to use as reference -- x: The x position, in world coordinates -- z: The z position, in world coordinates -- -- Returns The converted x and z coordinates -function cartographer.to_map_coordinates(map, x, z) - if not map or map.scale == 0 then +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) / map.scale + 0.5), math.floor(chunk.to(z) / map.scale + 0.5); + return math.floor(chunk.to(x) / self.scale + 0.5), math.floor(chunk.to(z) / self.scale + 0.5); end -- Periodically-called function to fill in maps and queue chunks for manual @@ -205,12 +213,8 @@ function cartographer.register_marker(id, name, textures) end end -function cartographer.is_filled(map, x, z) - if map == nil then - return false; - end - - return map.fill[(x - map.x) + ((z - map.z) * map.w)] ~= nil; +function Map.is_filled(self, x, z) + return self.fill[(x - self.x) + ((z - self.z) * self.w)] ~= nil; end -- Get an entry from a list for a given detail level diff --git a/map_formspec.lua b/map_formspec.lua index c82a3ee..eb90461 100644 --- a/map_formspec.lua +++ b/map_formspec.lua @@ -18,6 +18,14 @@ local MAP_NOISE = { flags = "defaults, absvalue", }; +local function map_is_filled(map, x, y) + return map:is_filled(x, y); +end + +local function map_get_marker(map, x, y) + return map:get_marker(x, y); +end + -- Get the variant of the tile at a given position -- prefix: The part of the tile texture name before the variant -- x: The X position of the tile (in map coordinates) @@ -185,7 +193,7 @@ function map_formspec.from_map(map, x, y, height_mode) w = formspec_width, h = formspec_height, - generate_map(map.x, map.z, map.w, map.h, x, y, map.detail, map.scale, height_mode, cartographer.is_filled, cartographer.get_marker, map), + generate_map(map.x, map.z, map.w, map.h, x, y, map.detail, map.scale, height_mode, map_is_filled, map_get_marker, map), }, formspec_width, formspec_height; end diff --git a/table.lua b/table.lua index 5020081..a5c7bca 100644 --- a/table.lua +++ b/table.lua @@ -94,7 +94,7 @@ end -- stack: The itemstack to convert -- -- Returns a table with the material values -function get_material_value(stack) +local function get_material_value(stack) local item_name = stack:get_name(); local item_count = stack:get_count();