localp={}localdata=require("Module:Datatable")localmathOps=require("Module:MathOps")localutils=require("Module:Utils")localc=utils-- As there is onlny one function relevant to colors I make only alias to utils Module to convenient naming "c - color"localframe=mw.getCurrentFrame()localbar="|"-- code for |localnl="\n"--Function to convert string "true/false" to actual boolean valuesfunctionresolveBoolParam(param)iftype(param)~="string"thenreturnutils.bool(param.args[1])endend--Function returning an average size across all maps stored in table maps.--If convertToMetres is set to true then result will be returned in square metresfunctionp.getAverageMapSize(convertToMetres)convertToMetres=resolveBoolParam(convertToMetres)--utils.bool(convertToMetres)localresult=0localsum=0locali=1whilemaps[i]do--going through all mapslocalmapTiles=maps[i].ASTilesif(type(mapTiles)~="table")thensum=sum+mapTileselse--in case mapTiles are described in multiple layerslocalj=1whilemapTiles[j]dosum=sum+mapTiles[j][1]--mapTiles are expected to be first parameterj=j+1endendi=i+1endifi>1theni=i-1end--as the index starts at 1 we must decrease the counter as the loop ends with incrementation of counter/index even after last map loopedsum=sum/i--making averageifconvertToMetresthenresult=p.toSMetres(sum)elseresult=sumendreturnmathOps.round(result)end--Call a function with a string parameter that will be resolved afterwardsfunctionp.getCountOfMaps()returnutils.getCount("map")endfunctionp.getCountOfRealms()returnutils.getCount("realm")end--Returns the biggest map from the maps table. Size is measured in Square Tiles.--returnName: [optional parameter], String -> Boolean, flag whether function should return Name of map or size value by defaultfunctionp.getBiggestMap(returnName)ifreturnName==nilthenreturnName=falseelseiftype(returnName)=="table"thenreturnName=utils.bool(returnName.args[1])orfalseendlocalmapId=0localresult=0localmapTileslocali=1whilemaps[i]domapTiles=maps[i].ASTilesif(type(mapTiles)~="table")thenifmapTiles>resultthenresult=mapTilesmapId=iendelse--in case mapTiles are described in multiple layerslocalj=1localsubTotal=0whilemapTiles[j]dosubTotal=subTotal+mapTiles[j][1]--mapTiles are expected to be first parameterj=j+1endifsubTotal>resultthenresult=subTotalmapId=iendendi=i+1endif(returnName)thenreturnmaps[mapId].nameendreturnresultend--Returns the smallest map from the maps table. Size is measured in Square Tiles.--returnName: [optional parameter], String -> Boolean, flag whether function should return Name of map or size value by defaultfunctionp.getSmallestMap(returnName)ifreturnName==nilthenreturnName=falseelseiftype(returnName)=="table"thenreturnName=utils.bool(returnName.args[1])orfalseendlocalmapIdlocalresult=0localmapTileslocali=1ifmaps[i].ASTilesthen--just a avoiding assigning magic constant so using first map as a starting pointresult=maps[i].ASTilesmapId=1endwhilemaps[i]domapTiles=maps[i].ASTilesif(type(mapTiles)~="table")thenifmapTiles<resultandmapTiles>0thenresult=mapTilesmapId=iendelse--in case mapTiles are described in multiple layerslocalj=1localsubTotal=0forj,mapLayerinipairs(mapTiles)dosubTotal=subTotal+mapLayer[1]--mapTiles are expected to be first parameterendifsubTotal<resultandsubTotal>0thenresult=subTotalmapId=iendendi=i+1endif(returnName)thenreturnmaps[mapId].nameendreturnresultend--Returns Count of realms based on map. If the parameter is not passed function use Page name insteadfunctionp.getCountOfRealmMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalrealmId=getRealmIdByMapName(map)returnp.getCountOfRealmMapByRealmId(realmId)endfunctionp.getCountOfRealmMapByRealmId(realmId)localresult=0localcurrentMaplocali=1whilemaps[i]docurrentMap=maps[i]ifcurrentMap.realm==realmIdthenresult=result+1endi=i+1endreturnresultendfunctionp.getCountOfRealmMapsByName(realm)iftype(realm)~="string"thenrealm=realm.args[1]ormw.title.getCurrentTitle().textendlocalrealmId=p.getRealmIdByRealm(realm)returnp.getCountOfRealmMapByRealmId(realmId)endfunctionp.getRealmIdByRealm(realm)iftype(realm)~="string"thenrealm=realm.args[1]ormw.title.getCurrentTitle().textendspec="^(.+) %(.+%)$"--page specification, ex.: "Silent Hill (Realm)"" >> "Silent Hill"ifstring.find(realm,spec)thenrealm=realm:match(spec)endfori,realmIteminipairs(realms)doifrealm==realmItem[1]thenreturnrealmItem.idendendreturn0end--Returns Realm ID based on map name passed as a parameterfunctiongetRealmIdByMapName(map)locali=1localcurrentMapwhilemaps[i]docurrentMap=maps[i]ifcurrentMap.name==mapthenreturncurrentMap.realmendi=i+1endreturn0end--Returns Realm name based on passed map name. If the function is called without parameter the function will use Page name as a map namefunctionp.getRealmNameByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendreturngetRealmNameById(getRealmIdByMapName(map))end--Returns Realm Name based on realm's IDfunctiongetRealmNameById(id)returnrealms[id][1]endfunctionp.toSMetres(number)returnnumber*64endfunctionp.toSTiles(number)returnnumber/64endfunctionp.getAltNameByMap(map)localresultlocalmapIdiftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendmapId=getMapIndexByMapName(map)ifmaps[mapId].altName==maps[mapId].nameormaps[mapId].altName==nilthen--if Map name is the same as its main name or doesn't have it at all return empty stringresult=""elseresult=maps[mapId].altNameendreturnresultendfunctiongetMapIndexByMapName(map)locali=1localcurrentMapwhilemaps[i]docurrentMap=maps[i]ifcurrentMap.name==mapthenreturniendi=i+1endreturn0endfunctionp.displayRealmIfExist(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalaltName=p.getAltNameByMap(map)localresult=""ifaltName~=""thenresult="or ''\""..altName.."\"'' "endreturnresultend----------------------------------------------------------------------------------------------------------id: [optional parameter], id of map from table mapsfunctionp.getMapName(id)iftype(id)=="table"andtype(id.args[1])~="nil"thenid=tonumber(id.args[1])elseiftype(id)=="table"thenid=getMapIndexByMapName(mw.title.getCurrentTitle().text)endreturnmaps[id].nameendfunctionp.getMapSizeByMap(map,convertToMetres)--TODO as the TealmsInfo template is planned to redisgn this part it will be needed to rewrite this functioniftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalmapId=getMapIndexByMapName(map)localvaluelocalareas=""if(type(maps[mapId].ASTiles)=="table")thenlocali=1whilemaps[mapId].ASTiles[i]doarea=maps[mapId].ASTiles[i]ifconvertToMetresthenvalue=utils.commaFormat(p.toSMetres(area[1]))elsevalue=area[1]endareas=areas..value.." ("..area[2]..")"if(type(maps[mapId].ASTiles[i+1])~="nil")then--areas = areas .. " '''<nowiki>" .. frame:expandTemplate{title = '!'} .. "</nowiki>''' "areas=areas.." '''"..bar.."''' "endi=i+1endreturnareaselseifconvertToMetresthenreturnp.toSMetres(maps[mapId].ASTiles)endreturnmaps[mapId].ASTilesendreturnareasendfunctionp.getMapSizeByMapInSMetres(map)returnp.getMapSizeByMap(map,true)endfunctionp.getMinHooksByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendreturnmaps[getMapIndexByMapName(map)].minHooksendfunctionp.getMaxHooksByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalmapId=getMapIndexByMapName(map)ifmaps[mapId].maxHooks==nilthenifmaps[mapId].minHooks~=nilthen--must be separated condition if case maxHooks is nilreturnmaps[mapId].minHooks+5--default difference between count of min and max of hooksendelsereturnmaps[mapId].maxHooksendendfunctionp.getMinPalletsByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendreturnmaps[getMapIndexByMapName(map)].minPalletsendfunctionp.getMaxPalletsByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendreturnmaps[getMapIndexByMapName(map)].maxPalletsend--returns a table with Outline name(s)functionp.getOutlineGrid(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalresult={}localmapId=getMapIndexByMapName(map)locali=1localimgIndex=isListedInImagesByMapId(mapId)iftype(maps[mapId].ASTiles)=="table"thenwhilemaps[mapId].ASTiles[i]doif(imgIndex~=0)thenresult[i]=mapImages[imgIndex].outline[i]..".png"elseresult[i]=p.resolveOutlineNameFromGrid(mapId,i)..".png"endi=i+1endelseif(imgIndex~=0)thenresult[i]=mapImages[imgIndex].outline..".png"elseresult[i]=p.resolveOutlineName(mapId)..".png"endendreturnresultendfunctionisListedInImagesByMapId(mapId)locali=1whilemapImages[i]doif(mapImages[i].id==mapId)thenreturniendi=i+1endreturn0endfunctionp.resolveOutlineNameFromGrid(mapId,index)localoutlineMapName=utils.resolveFileName(maps[mapId].name)localoutlineSubName=utils.resolveFileName(maps[mapId].ASTiles[index][2])returnoutlineMapName.."Outline_"..outlineSubNameendfunctionp.resolveOutlineName(mapId)--These two functions should be merged --TODOlocaloutlineMapName=utils.resolveFileName(maps[mapId].name)returnoutlineMapName.."Outline"endfunctionp.resolveImageNameByMap(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalrealmId=getRealmIdByMapName(map)localmapId=getMapIndexByMapName(map)localrealmAbbr=realms[realmId][2]localmapAltName=""localimgIndex=isListedInImagesByMapId(mapId)if(imgIndex~=0)thenreturnmapImages[imgIndex].image..".png"elseiftype(maps[mapId].altName)~="nil"thenmapAltName=utils.resolveFileName(maps[mapId].altName)else--Not the happies name of variable but it works as this else branch is only for rare casesmapAltName=utils.resolveFileName(maps[mapId].name)endreturn"IconMap "..realmAbbr.." "..mapAltName..".png"endfunctiongetMapReleaseByIndex(mapIndex)returnmaps[mapIndex].releaseendfunctiongetThemeByIndex(mapIndex)locali=1localmapId=maps[mapIndex].idwhilethemes[i]doifthemes[i].mapId==mapIdthenreturnthemes[i].landmarksound..".ogg"endi=i+1endreturnnilendfunctionp.assembleRealmsInfo(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocali=1localmapIndex=getMapIndexByMapName(map)localparamTable={}localoutlines=p.getOutlineGrid(map)paramTable["map"]=p.getMapName(mapIndex)paramTable["altmap"]=p.getAltNameByMap(map)paramTable["image"]=p.resolveImageNameByMap(map)whileoutlines[i]doparamTable["outline"..i]=outlines[i]i=i+1endparamTable["realm"]="[["..p.getRealmNameByMap(map).."]]"paramTable["area"]=p.getMapSizeByMap(map)paramTable["area2"]=p.getMapSizeByMapInSMetres(map)if(type(maps[mapIndex].ASTiles)=="table")thenlocalmapTiles=maps[mapIndex].ASTileslocalareaTotal=0i=1whilemapTiles[i]doareaTotal=areaTotal+mapTiles[i][1]--mapTiles are expected to be first parameteri=i+1endparamTable["area3"]=areaTotalparamTable["area4"]=utils.commaFormat(p.toSMetres(areaTotal))endparamTable["minhooks"]=p.getMinHooksByMap(map)paramTable["maxhooks"]=p.getMaxHooksByMap(map)paramTable["minpallets"]=p.getMinPalletsByMap(map)paramTable["maxpallets"]=p.getMaxPalletsByMap(map)if(type(getMapReleaseByIndex(mapIndex))~="nil")thenparamTable["release"]="[[Patch "..getMapReleaseByIndex(mapIndex).."]]"endlocaltheme=getThemeByIndex(mapIndex)if(type(theme)=="string")thenparamTable["landmarksound"]=themeendmw.log(mw.dumpObject(paramTable))returnframe:expandTemplate{title='RealmsInfo',args=paramTable}--string.char(10)endfunctionp.assembleMapPageHeader(map)iftype(map)~="string"thenmap=map.args[1]ormw.title.getCurrentTitle().textendlocalresultlocalmapCount=p.getCountOfRealmMap(map)result=p.assembleRealmsInfo(map)result=result.."\n\n'''"..map.."''' "..p.displayRealmIfExist(map)ifmapCount>1thenresult=result.." is one of '''"..frame:expandTemplate{title="clr",args={2,p.getCountOfRealmMap(map)}}.."''' Maps"elseresult=result.." is the only map"endresult=result.." for the [["..p.getRealmNameByMap(map).."]] Realm."returnresultendfunctionp.assembleMapsForRealms(realm)localrealmId=0localresult=""localmaplocaloutlineslocali=1localj=1ifrealm==nilthenrealmId=p.getRealmIdByRealm(mw.title.getCurrentTitle().text)elseiftype(realm)=="table"thenrealmId=p.getRealmIdByRealm(realm.args[1]ormw.title.getCurrentTitle().text)elseiftype(realm)=="string"thenrealmId=p.getRealmIdByRealm(realm)endifrealmId==0thenmw.log("Missing parameter \"realm\". Please add the parameter into invocation.\n\n'''Example: '''{{#Invoke:Maps|assembleMapsForRealms|name_of_realm}}\n\n")return"Missing parameter \"realm\". Please add the parameter into invocation.\n\n'''"..c.clr("Example","red")..":''' {{#Invoke:Maps|assembleMapsForRealms|'''"..c.clr("name_of_realm","orange").."'''}}\n\n"endresult="{| class=\"wikitable\"\n"whilemaps[i]doif(maps[i].realm==realmId)thenmap=maps[i].nameresult=result.."|<center>[["..map.."]]</center>\n"result=result.."[[File:"..p.resolveImageNameByMap(map).."|center|frameless|link="..map.."]]"j=1outlines=p.getOutlineGrid(map)whileoutlines[j]do--loop for cases with multiple outlinesresult=result.."[[File:"..outlines[j].."|center|framelss|200px|link="..map.."]]"j=j+1endresult=result.."\n"--just for keeping the same formatting, functionally completely uselessendi=i+1endresult=result.."|}"mw.log(result)returnresultendfunctionp.assembleSortedMapsTableBySize()localresult=""localcenter="style=\"text-align:center\""utils.sortMapsByASTiles()localmapRates=p.getRatesOfMapTable()localmapRatelocalindexlocalbgColorresult="{| class=\"wikitable\"\n|-"..nlresult=result.."! Rank !! Map !! Size in ''square Tiles'' !! Size in m<sup>2</sup>\n"locali=1whilemapRates[i]domapRate=mapRates[i]result=result.."|- "..center..nlresult=result.."! "ifmapRate.count>1then--if count of maps of such size is more than oneresult=result.."rowspan=\""..mapRate.count.."\"| "endresult=result..i..nl--printing map(s) RateglobalIndex=getAbsolutePosition(mapRates,i)forindex=globalIndex,globalIndex+mapRate.count-1,1do--there must be -1 due to offset in lists as the globalIndex starts with at index of first map current Rate--mw.log("i: " .. i .. " | index: " .. index .. " | Map: ".. maps[index].name .. " |||| index == gobalIndex: " .. index .. " == " .. globalIndex .. " |||| mapRate.count > 1: " .. mapRate.count .. " > " .. 1)if(index>globalIndex)then--if the index is higher than starting position means if it's not the first iteration then do the trickresult=result.."|- "..center..nlendbgColor=realms[maps[index].realm].color--In map must be correct realmID otherwise the code fails--mw.log(bgColor)result=result.."| style=\"background:#"..bgColor..";color:"..utils.resolveTextColorByBackground(bgColor)..";\" | "..maps[index].name..nl--TODO complete stylesif(index==globalIndexandmapRate.count>1)thenresult=result.."| rowspan=\""..mapRate.count.."\"| "..mapRate.size..nlresult=result.."| rowspan=\""..mapRate.count.."\"| "..utils.commaFormat(p.toSMetres(mapRate.size))..nlelseif(index==globalIndex)thenresult=result.."| "..mapRate.size..nlresult=result.."| "..utils.commaFormat(p.toSMetres(mapRate.size))..nlendendi=i+1endresult=result.."|}"mw.log(result)returnresultendfunctionp.getRatesOfMapTable()locali=1localresult={}whilemaps[i]do--go through all mapslocalj=1localrate=nillocalsize=maps[i].ASTilesiftype(size)=="table"thensize=utils.getSumOfASTiles(maps[i].ASTiles)endwhileresult[j]do--everytime look for if there is already the size of map logged in result tableifresult[j].size==sizethen--if so then store it and skip the restrate=result[j]breakendj=j+1endifrate==nilthen--if such size wasn't found in rate table then create a new one, "j" doesn't have to be increased as it's already increased by last go-through of loop aboveresult[j]={}result[j].count=1--we do not store the size as the index in table will later serve as a rank (after we sort the table)result[j].size=sizeelseresult[j].count=result[j].count+1-- "j" doesn't have to be decreased as the loop above breaked out before incrementationendi=i+1endutils.sortMapRates(result)--sorting will cause that the index serve as an rate for tablereturnresultend--function returns an index reflecting a position in sorted maps table based on current index in mapRates tablefunctiongetAbsolutePosition(mapRates,currentIndex)locali=1localresult=1whilei<currentIndexdoresult=result+mapRates[i].count--sum count of map from every previous rate until you reach the current indexi=i+1endreturnresultendreturnp