Module
ServerMap
From Dogcraft Wiki
(fixed some errors. still WIP) |
(commented today additions) Β |
||
(5 intermediate revisions by the same user not shown) | |||
Line 25: | Line 25: | ||
function generate() | function generate() | ||
-- the number of map tiles is double the scale number + 1. As we start the loops with 0, we only need to set the variable to be double the scale number | |||
local maxWidthHeight = scale * 2 | |||
-- tileSize: the tile size number used by bluemap. 1=500x500 blocks per image, 2=2500x2500 blocks per image | |||
-- tilePixels: the width in blocks represented by a tile - correlates directly to tileSize | |||
-- center: the index (in both column and row) for the center tile. for tileSize == 1 this is equal to the scale number | |||
local tileSize = 1 | |||
local tilePixels = 500 | |||
local center = scale | |||
Β Β -- output variable will hold the entire output of this module | |||
-- first we add the outer map container and map grid container divs | |||
local output = "<div id=\"outer-map-container\">\n" | local output = "<div id=\"outer-map-container\">\n" | ||
output = output .. "<div class=\"map-grid-container\">\n" | output = output .. "<div class=\"map-grid-container\"" | ||
-- at scale numbers above 7, switch to using the lower resolution 2500x2500 block tiles | |||
if scale >= 7 then | |||
-- first calculate the number of columns and rows needed | |||
maxWidthHeight = math.floor((scale + 0.5) / 2.5) - 1 | |||
-- the above calculation could result in a uneven number, so compensate for that | |||
if maxWidthHeight % 2 > 0 then | |||
maxWidthHeight = maxWidthHeight + 1 | |||
end | |||
-- set tileSize and tilePixels to the new values | |||
tileSize = 2 | |||
tilePixels = 2500 | |||
-- with these tiles we can no longer achieveΒ n * 1000 + 500 in size from the tiles alone. | |||
-- To keep the scale argument consistent we need to upscale our tiles to fit the requirements (any overflow is hidden by the outer map container) | |||
-- check if our tiles match the desired size exactly. If not, add two more tiles in both width and height to provide the extra bit along the edges | |||
if (scale + 0.5) % 2.5 > 0 then | |||
maxWidthHeight = maxWidthHeight + 2 | |||
-- calculate the scaling needed to achieve the exact desired size | |||
local width = ((maxWidthHeight + 1) * 2.5) / (scale + 0.5) | |||
-- calculate the offset towards the top-left to stay centered exactly on the center tile | |||
local topLeft = (width / 2) - 0.5 | |||
-- add the scaling and offset to the map grid container | |||
output = output .. " style=\"position: relative; width: " .. (width * 100) .. "%; top: -" .. (topLeft * 100) .. "%; left: -" .. (topLeft * 100) .. "%;\"" | |||
end | |||
-- get the new center index | |||
center = maxWidthHeight / 2 | |||
end | |||
-- end of <div class=\"map-grid-container\" | |||
output = output .. ">\n" | |||
-- now add the link that is visible when hovering over the map | |||
output = output .. "[https://dogcraft.net/map#" .. world .. ":" .. xCoord .. ":0:" .. zCoord .. ":250:0:0:0:0:perspective Click for full map]\n" | output = output .. "[https://dogcraft.net/map#" .. world .. ":" .. xCoord .. ":0:" .. zCoord .. ":250:0:0:0:0:perspective Click for full map]\n" | ||
-- if a overlay was given, add it now | |||
if overlay ~= "" then | if overlay ~= "" then | ||
output = output .. "<div class=\"map-overlay-container\">\n" .. overlay .. "\n</div>\n" | output = output .. "<div class=\"map-overlay-container\">\n" .. overlay .. "\n</div>\n" | ||
end | end | ||
-- loop over all required map tiles. i is the row iterator, j is the column iterator | |||
for i = 0, maxWidthHeight do | |||
for i = 0, | for j = 0, maxWidthHeight do | ||
for j = 0, | |||
-- create the grid child div for the current tile | |||
output = output .. "<div class=\"map-grid-child" | output = output .. "<div class=\"map-grid-child" | ||
if i == | |||
if j == | -- if both row and column are equal to the center number, the current tile is the very center tile that will have the marker in it and needs this extra css class | ||
if i == center then | |||
if j == center then | |||
output = output .. " inner-map-container" | output = output .. " inner-map-container" | ||
end | end | ||
end | end | ||
-- if we are on the first tile of the last row, add the class to round the bottom left corner and if we are on the last tile of the last row, add the class to round the bottom right corner | |||
if i == maxWidthHeight then | |||
if j == 0 then | |||
output = output .. " map-grid-bottom-left" | |||
end | |||
if j == maxWidthHeight then | |||
output = output .. " map-grid-bottom-right" | |||
end | |||
end | |||
-- add the grid-column and grid-row css parameters according to our position (we need to add 1 to both as css doesnt like a row or column of 0) | |||
output = output .. "\" style=\"grid-row: " .. (i + 1) .. "; grid-column: " .. (j + 1) .. ";\">" | output = output .. "\" style=\"grid-row: " .. (i + 1) .. "; grid-column: " .. (j + 1) .. ";\">" | ||
output = output .. "https://map.dogcraft.net/maps/" .. world .. "/tiles/ | -- here we add the actual image tile of the map | ||
output = output .. "https://map.dogcraft.net/maps/" .. world .. "/tiles/" .. tileSize .. "/x" .. (math.floor(xCoord / tilePixels) + (j - center)) .. "/z" .. (math.floor(zCoord / tilePixels) + (i - center)) .. ".png\n" | |||
if i == | -- if we are on the center tile, we need to add the marker | ||
if j == | if i == center then | ||
if j == center then | |||
local xMod = xCoord % | -- calculate the marker position within the tile | ||
local xMod = xCoord % tilePixels | |||
local left = 0 | local left = 0 | ||
Line 61: | Line 132: | ||
end | end | ||
local zMod = zCoord % | local zMod = zCoord % tilePixels | ||
local top = 0 | local top = 0 | ||
Line 70: | Line 141: | ||
end | end | ||
-- and add the marker at that position. The css calc here is used to correct for the size of the actual marker icon | |||
output = output .. "<div id=\"marker-wrapper\" style=\"left: calc(" .. left .. "% - 30px); top: calc(" .. top .. "% - 70px);\">\n" | output = output .. "<div id=\"marker-wrapper\" style=\"left: calc(" .. left .. "% - 30px); top: calc(" .. top .. "% - 70px);\">\n" | ||
output = output .. "<i class=\"fa-solid fa-location-dot\"></i>\n" | output = output .. "<i class=\"fa-solid fa-location-dot\"></i>\n" | ||
Line 77: | Line 149: | ||
end | end | ||
-- close the current grid-child div | |||
output = output .. "</div>\n" | output = output .. "</div>\n" | ||
Line 82: | Line 155: | ||
end | end | ||
-- close the map-grid-container and outer-map-container divs | |||
output = output .. "</div>\n" | output = output .. "</div>\n" | ||
output = output .. "</div>\n" | output = output .. "</div>\n" | ||
-- and finally return the output | |||
return output | return output | ||
Line 91: | Line 166: | ||
-- The main function called on #invoke via the template | -- The main function called on #invoke via the template | ||
function p. | function p.Map(frame) | ||
Β Β Β local args = {} | Β Β Β local args = {} | ||
Β Β Β -- get the arguments | Β Β Β -- get the arguments |
Latest revision as of 16:55, 31 October 2024
Documentation for this module may be created at Module:ServerMap/doc
-- Copyright (c) 2024, XPModder, Dogcraft.net and contributors
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
-- to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--
-- End license text.
-- A module creating a map of the server by utilising images from the Bluemap server plugin
local p = {}
local scale = 0
local xCoord = 0
local zCoord = 0
local world = "sheltie"
local overlay = ""
function generate()
-- the number of map tiles is double the scale number + 1. As we start the loops with 0, we only need to set the variable to be double the scale number
local maxWidthHeight = scale * 2
-- tileSize: the tile size number used by bluemap. 1=500x500 blocks per image, 2=2500x2500 blocks per image
-- tilePixels: the width in blocks represented by a tile - correlates directly to tileSize
-- center: the index (in both column and row) for the center tile. for tileSize == 1 this is equal to the scale number
local tileSize = 1
local tilePixels = 500
local center = scale
-- output variable will hold the entire output of this module
-- first we add the outer map container and map grid container divs
local output = "<div id=\"outer-map-container\">\n"
output = output .. "<div class=\"map-grid-container\""
-- at scale numbers above 7, switch to using the lower resolution 2500x2500 block tiles
if scale >= 7 then
-- first calculate the number of columns and rows needed
maxWidthHeight = math.floor((scale + 0.5) / 2.5) - 1
-- the above calculation could result in a uneven number, so compensate for that
if maxWidthHeight % 2 > 0 then
maxWidthHeight = maxWidthHeight + 1
end
-- set tileSize and tilePixels to the new values
tileSize = 2
tilePixels = 2500
-- with these tiles we can no longer achieve n * 1000 + 500 in size from the tiles alone.
-- To keep the scale argument consistent we need to upscale our tiles to fit the requirements (any overflow is hidden by the outer map container)
-- check if our tiles match the desired size exactly. If not, add two more tiles in both width and height to provide the extra bit along the edges
if (scale + 0.5) % 2.5 > 0 then
maxWidthHeight = maxWidthHeight + 2
-- calculate the scaling needed to achieve the exact desired size
local width = ((maxWidthHeight + 1) * 2.5) / (scale + 0.5)
-- calculate the offset towards the top-left to stay centered exactly on the center tile
local topLeft = (width / 2) - 0.5
-- add the scaling and offset to the map grid container
output = output .. " style=\"position: relative; width: " .. (width * 100) .. "%; top: -" .. (topLeft * 100) .. "%; left: -" .. (topLeft * 100) .. "%;\""
end
-- get the new center index
center = maxWidthHeight / 2
end
-- end of <div class=\"map-grid-container\"
output = output .. ">\n"
-- now add the link that is visible when hovering over the map
output = output .. "[https://dogcraft.net/map#" .. world .. ":" .. xCoord .. ":0:" .. zCoord .. ":250:0:0:0:0:perspective Click for full map]\n"
-- if a overlay was given, add it now
if overlay ~= "" then
output = output .. "<div class=\"map-overlay-container\">\n" .. overlay .. "\n</div>\n"
end
-- loop over all required map tiles. i is the row iterator, j is the column iterator
for i = 0, maxWidthHeight do
for j = 0, maxWidthHeight do
-- create the grid child div for the current tile
output = output .. "<div class=\"map-grid-child"
-- if both row and column are equal to the center number, the current tile is the very center tile that will have the marker in it and needs this extra css class
if i == center then
if j == center then
output = output .. " inner-map-container"
end
end
-- if we are on the first tile of the last row, add the class to round the bottom left corner and if we are on the last tile of the last row, add the class to round the bottom right corner
if i == maxWidthHeight then
if j == 0 then
output = output .. " map-grid-bottom-left"
end
if j == maxWidthHeight then
output = output .. " map-grid-bottom-right"
end
end
-- add the grid-column and grid-row css parameters according to our position (we need to add 1 to both as css doesnt like a row or column of 0)
output = output .. "\" style=\"grid-row: " .. (i + 1) .. "; grid-column: " .. (j + 1) .. ";\">"
-- here we add the actual image tile of the map
output = output .. "https://map.dogcraft.net/maps/" .. world .. "/tiles/" .. tileSize .. "/x" .. (math.floor(xCoord / tilePixels) + (j - center)) .. "/z" .. (math.floor(zCoord / tilePixels) + (i - center)) .. ".png\n"
-- if we are on the center tile, we need to add the marker
if i == center then
if j == center then
-- calculate the marker position within the tile
local xMod = xCoord % tilePixels
local left = 0
if xMod < 0 then
left = (500 + xMod) / 5.01
else
left = xMod / 5.01
end
local zMod = zCoord % tilePixels
local top = 0
if zMod < 0 then
top = (500 + zMod) / 5.01
else
top = zMod / 5.01
end
-- and add the marker at that position. The css calc here is used to correct for the size of the actual marker icon
output = output .. "<div id=\"marker-wrapper\" style=\"left: calc(" .. left .. "% - 30px); top: calc(" .. top .. "% - 70px);\">\n"
output = output .. "<i class=\"fa-solid fa-location-dot\"></i>\n"
output = output .. "</div>\n"
end
end
-- close the current grid-child div
output = output .. "</div>\n"
end
end
-- close the map-grid-container and outer-map-container divs
output = output .. "</div>\n"
output = output .. "</div>\n"
-- and finally return the output
return output
end
-- The main function called on #invoke via the template
function p.Map(frame)
local args = {}
-- get the arguments
if frame == mw.getCurrentFrame() then
args = frame:getParent().args
else
args = frame.args
end
-- validate the arguments and populate the variables with good values
local scaleParam = args.scale
if scaleParam == nil then
scaleParam = 0
end
scale = tonumber(scaleParam)
local x = args.xCoord
if x == nil then
x = 0
end
xCoord = tonumber(x)
local z = args.zCoord
if z == nil then
z = 0
end
zCoord = tonumber(z)
local worldParam = args.world
if worldParam == nil then
worldParam = "sheltie"
end
world = tostring(worldParam)
world = mw.text.trim(world)
world = mw.ustring.lower(world)
local overlayParam = args.overlay
if overlayParam == nil then
overlayParam = ""
end
overlay = tostring(overlayParam)
-- finally generate the map
return generate()
end
return p