Module:Minimap

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

local string, table, lu = loader.require('String', 'Table', 'LibU') local maps, aliases, zoneData, zoneAliases = loader.loadData('Minimap/Data', 'Minimap/Aliases', 'Zone/Data', 'Zone/Aliases')

local p = {}

local function getMapData(location) location = location:lower location = aliases[location] or aliases[zoneAliases[location]] or location local mapDt = maps[location] if not mapDt then local zDt = zoneData[zoneAliases[location] or location] if zDt and zDt.parent then mapDt = maps[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 return p._getMap(mapDt, x, y, z, 238.4, 238.4, '8x', { 'redtarget' }) 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 or 71 local z = args.z   local width = args['width'] or args['size'] or 150 local height = args['height'] or args['size'] or 150 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 lu.assertTrue(location, 'location must be specified', 0) lu.assertTrue(x, 'x must be specified', 0) lu.assertTrue(z, 'z must be specified', 0) return p._getMap(location, x, y, z, width, height, scale, markers) end

function p._getMap(location, x, y, z, width, height, pGameScale, markers) -- 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 lu.assertTrue(mapData, 'Invalid location %q', 2, location) -- 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] if mrk == 'fairysoul' or mrk == 'soul' or mrk == 'fairy' then mrk = '' elseif mrk == 'circle' or mrk == 'redcircle' or mrk == 'ring' or mrk == 'redring' then mrk = '' else -- others: use redtarget mrk = '' end 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