Module:Minimap

-- local loader = require('Module:Loader') local getArgs = require('Module:Arguments').getArgs

local string, table, safeResponse = loader.require('String', 'Table', 'SafeResponse') local moduleData, moduleDatasheet, moduleAliases, zoneData, zoneAliases = loader.loadData('Minimap/Data', 'Minimap/Datasheet', 'Minimap/Aliases', 'Zone/Data', 'Zone/Aliases')

local p = {}

local function getMapData(location) location = location:lower location = moduleAliases[location] or moduleAliases[zoneAliases[location]] or location local mapDt = moduleDatasheet[location] if not mapDt then local zDt = zoneData[zoneAliases[location] or location] if zDt and zDt.parent then mapDt = moduleDatasheet[zDt.parent] end end return mapDt, location end

-- returns blank if not valid; fails silently function p.getMinimapForInfobox(frame) -- Note: Do NOT use 'getArgs' here; as this is invoked directly from the infobox, we don't want it fetching parent variables local args = frame.args or frame local location = args.minimap_location or args.location or args[1] local x, y, z = args.x, args.y or 71, args.z   if not location or not x or not z or location ==  or x ==  or z ==  then return  end location = location:gsub('%[*', ):gsub('%]*', ) local mapDt = getMapData(location) if not mapDt then return '' -- fail silently end local success, result = safeResponse.call(p._getMap, mapDt, x, y, z, 238.4, 238.4, '8x', { 'redtarget' }) return result end

function p.getMap(frame) local args = getArgs(frame) local location = args.minimap_location or args.location or args[1] local x = args.x   local y = args.y    local z = args.z    local width = args['width'] or args['size'] local height = args['height'] or args['size'] local scale = args['scale'] -- true in-game scale - will default to image scale local markers = {} if args['marker'] then table.push(markers, args['marker']) end local i = 2 while args['marker' .. i] do table.push(markers, args['marker' .. i]) i = i + 1 end local success, result = safeResponse.call(p._getMap, location, x, y, z, width, height, scale, markers) return result end

--  function p._getMap(location, x, y, z, width, height, pGameScale, markers) x = tonumber(x) y = tonumber(y) or 72 z = tonumber(z) width = width or 150 height = height or 150 -- location can be a mapData table or a string local mapData if type(location) ~= 'table' then mapData = getMapData(location) else mapData = location end -- Check for errors if not x or not y or not z then error({ type='Minimap/BadCoordinates' }) end if not mapData then error({ type='Minimap/BadLocation', format={tostring(location)} }) end -- Find what scale the template wants it on (based on a 64x64 in-game block size) local gameScale = 0.125 if pGameScale then -- If value is '8x' format then zoom out by that factor; otherwise treat it as a percentage local hasMulti, t, gsMulti = string.find(pGameScale, '(.*)x') -- don't change this to `:find`, as input may be a number if hasMulti ~= nil then gameScale = 1 / gsMulti else gameScale = pGameScale / 100 end end -- Stored map data local imageScale = mapData.imageScale local topLeftCoord = mapData.topLeftCoord local imageDimensions = mapData.imageDimensions -- Find the difference between tile size on the map and the target scale 1x tile size local imageTileWidth = 1 / imageScale local gameTileWidth = 64 -- don't change, this number effects all 'scale' values, as this is the base! local imgScaleToGameScaleMulti = gameTileWidth / imageTileWidth -- how much the image needs to be scale to be the specified game scale at 100%

-- How much to scale actual image on the page based on 'true scale' desired, and the images default world scale local bgScale = gameScale * imgScaleToGameScaleMulti-- * (true and imgScaleToGameScaleMulti or (1/imgScaleToGameScaleMulti)) -- Final scale to apply to everything (other than the background itself) local scale = (1 / imageScale) * bgScale -- How much the background should be moved so the desired coordinate ends up in the center of the minimap local imgOffsetX = -(-topLeftCoord[1] + x) * scale + (width * 0.5) local imgOffsetY = -(-topLeftCoord[2] + z) * scale + (height * 0.5) local map = mw.html.create('div') :addClass('hsw-minimap') :addClass(mapData.imageClass) :css{ width = width .. 'px', height = height .. 'px', ['background-position'] = imgOffsetX .. 'px ' .. imgOffsetY .. 'px', ['background-size'] = (imageDimensions[1]*bgScale) .. 'px',--leaving off the height has it auto scale }   -- since crisp edges looks bad when zoomed out (vs zoom in), remove it if the scale desired is larger than the image scale if 1 / scale > imageScale then map:addClass('no-rendering') end if markers then for i,markerStr in ipairs(markers) do	   	local t = string.split(markerStr, ';') local mrk,coords = t[1], t[2] mrk = moduleData.markerData[ moduleData.markerAliases[mrk] or "redtarget" ] local mTag = map:tag('span'):addClass('minimap-marker'):wikitext(mrk) -- If coordinates provide use them; otherwise it defaults to center if coords then coords = string.split(coords, ',') -- get market x/z local mx,mz = coords[1], (#coords > 2 and coords[3] or coords[2]) -- make coordinates relative to center mx = mx - x	   		mz = mz - z	    		-- get marker offset local mox, moy = mx * scale, mz * scale -- apply to marker mTag:css{ left = mox .. 'px', top = moy .. 'px' } end end end return map end

return p