Warframe вики
Warframe вики
Warframe вики
6290
страниц
Модуль:Дроп
Данные

Модуль для автоматизации таблиц дропов. Использует базу Модуль:Дроп/Данные. Также доступен Модуль:ДропПеревод

Используется шаблонами

local p = {}
local DropData = mw.loadData( 'Модуль:Дроп/Данные' )
local MissionData = mw.loadData( 'Модуль:Миссия/Данные' )
local Shared = require( "Модуль:Функции" )
local Mods = require( "Модуль:Мод" )
local Relics = require( "Модуль:Реликвия" )
local Icons = require( "Модуль:Иконка" )

local rotationOrder={'Награда',
	'A','А','B','В','C','С','D',
	'Ротация A','Ротация А','Ротация B','Ротация В','Ротация C','Ротация С','Ротация D',
	'Бронзовый','Серебряный','Золотой','Легендарный',
	'Бонус','Обычный','Средний','Сложный',
	'Этап 0','Этапы 0-1','Этап 1','Этапы 1-2','Этап 2','Этапы 2-3','Этап 3',
	'Этапы 3-4','Этап 4', 'Этапы 4-5','Этап 5','Этапы 5-6','Этап 6'}

local cTarget = {
		['Мод'] = 'modChance',
		['Эндо'] = 'modChance',
		['Обломки'] = 'itemChance',
		['Предмет'] = 'itemChance',
		['Мистификатор'] = 'itemChance',
		['Релик'] = 'itemChance',
		['Часть'] = 'itemChance',
	}
local chanceField = {ModDrops="modChance",itemsBps="itemBpChance",extraItems="extraItemChance",Resources="resourceChance",Sigils="sigilChance",Relics="relicChance",}
	
function missionType(Mission)
	return toNil(Mission.Link) and Mission.Link..'|'..(Mission.Type or '') or Mission.Type
end

function p.testEnames()
local a = {}
local b	= {}
	local function name(thing)
		if type(thing)=='table' then return thing[1]  else return thing end
	end

	for sName, Data in pairs(DropData) do
		if not Data.Type then
		if Data.Ename then
			if Data.Link and not a[Data.Link] then
				a[Data.Link] = name(Data.Ename)
			elseif Data.Link then
				--mw.log (Data.Link, a[Data.Link], Data.Ename)
			else 
				b[sName] = name(Data.Ename)
				--mw.log (b[sName], '-', sName)
			end
	
		end
	end
end
--mw.logObject(b)
end

function p.printAllMissions()
	local stack = mw.html.create('')
	for mName, Data in Shared.skpairs(DropData) do
		if Data.Type == 'Миссия' then stack:node(p.printMissionTable({args={mName}})) end
	end
	return stack
end

--сравнивает название и ссылку предмета с запрошенными
function gate(Drop,targetName,targetLink)
	if targetLink then
		if targetName then
			return (targetName==Drop.Name and targetLink==Drop.Link)
		else
			return targetLink==Drop.Link
		end
	else return targetName==Drop.Name end
end

local function getMissionName(Tier)
	local ID, RJ
	if type(MissionData.MissionID[Tier])=='table' then
				ID= MissionData.MissionID[Tier][1] 
	else ID= MissionData.MissionID[Tier] or Tier end
	if not toNil(ID) or MissionData.MissionDetails[ID]==nil then return ID end
	
	local mName = missionType(MissionData.MissionDetails[ID])
	if MissionData.MissionDetails[ID].Tileset == "Рэйлджек" then 
		RJ = '<span class="invertableIcon">[[File:Рэйлджек иконка вики.svg|15px|link=Рэйлджек]]</span> ' 
	end
	if mName then mName  = '[['..mName..']]' end
	return RJ and RJ..mName or mName
end

--возаращает список итсточников выпадения запрошенного предмета
function p.dropItem(frame)
	local targetName = toNil(frame.args[1])
	local targetLink = toNil(frame.args[2])
	local regName = {}
	local tableTitles={'A','B','C','D'}
	
	local missionCart={}
	local bountyCart={}
	local enemyCart={}
	local containerCart={}
	
	local codeReuse = { --проходит по указанным полям
			'Drops',
			'ModDrops',
			'Resources',
			'extraItems',
		}
	
	for sName, Source in pairs(DropData) do
		if type(Source.MissionDrops)=="table" then
			local mName
			for rotation, DT in pairs(Source.MissionDrops) do
				for _, Drop in pairs(DT) do
					if gate(Drop,targetName,targetLink) then 
						mName = mName or getMissionName(Source.Tier)
						if not missionCart[mName] then missionCart[mName]={} end
						if not missionCart[mName][Source.Link] then missionCart[mName][Source.Link]={} end
						insertSource(missionCart[mName][Source.Link],Drop,Source,rotName(rotation),nil,true)
						
						if not regName[mName] then regName[mName] = {} end
						regName[mName][Source.Link]=regName[mName][Source.Link] or MissionData.MissionID[Source.Tier]
					end
				end
			end
		end
		
		if type(Source.BountyDrops)=="table" then
			local mName
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if gate(Drop,targetName,targetLink) then
							mName = mName or getMissionName(Source.Tier)
							if not bountyCart[mName] then bountyCart[mName]={} end
							if not bountyCart[mName][Source.Link] then bountyCart[mName][Source.Link] = {} end
							if not bountyCart[mName][Source.Link][tier] then bountyCart[mName][Source.Link][tier] = {} end
							insertSource(bountyCart[mName][Source.Link][tier],Drop,Source,tableTitles[vName],nil,true)
						end
					end
				end
			end
		end
		
		for _, tab in pairs(codeReuse) do
			if Source[tab] and type(Source[tab])=="table" then
				for i, Drop in pairs(Source[tab]) do
					if gate(Drop,targetName,targetLink) then
						if Source.Type ~= 'Контейнер' then
							insertSource(enemyCart,Drop,Source,sName,Source[chanceField[tab]])
						else
							insertSource(containerCart,Drop,Source,sName,Source[chanceField[tab]])
						end
					end
				end
			end
		end
	end
	
	--рендерит список миссий и заказов с тултипами для отображения в статье
	local mCart=mw.html.create()
	local bountyTime
	for _, Target in pairs({missionCart,bountyCart}) do
		for mName, Missions in Shared.skpairs(Target) do
			mCart:wikitext(mName..' (')
			local notFirst=false
			for regionName, Regions in Shared.skpairs(Missions) do
				if notFirst then mCart:wikitext(', ')
							else notFirst=true 
				end
				local bTooltip, mList = {}, {}
				if bountyTime then
					for tier, Drops in Shared.ordpairs(Regions,rotationOrder) do
						table.insert(bTooltip,'<b>'..tier..'</b>')
						for _, drop in pairs(Drops) do
							table.insert(bTooltip,drop)
						end
					end
				else
					
					if regName[mName] and type(regName[mName][regionName])=='table' then -- добавляет список миссий для миссий
						for _,ID in pairs(regName[mName][regionName]) do
							table.insert(mList,(MissionData.MissionDetails[ID].Node or '')..', '..(MissionData.MissionDetails[ID].Planet or ''))
						end
					elseif regName[mName] and regName[mName][regionName] then
						local ID = regName[mName][regionName]
						table.insert(mList,(MissionData.MissionDetails[ID].Node or '')..', '..(MissionData.MissionDetails[ID].Planet or ''))
					end
				end
				if mList[1] then table.insert(mList,1,"<br/><b>Локации:</b>") end
				mCart:tag('span'):addClass('acronymTooltip text-tooltip')
					:attr('data-param',table.concat(bountyTime and bTooltip or Regions,'<br/>')..table.concat(mList,'<br/>'))
					:wikitext(regionName):done()
			end
			mCart:wikitext(')<br/>')
		end
		bountyTime=true --на втором запуске пройдёт по альтернативной версии алгоритма
	end

	table.sort(containerCart)
	table.sort(enemyCart)
	local eBlock = enemyCart[1]~=nil
	local cBlock = containerCart[1]~=nil
	local mBlock
	for i in pairs(missionCart) do	if toNil(i) then mBlock=true break end end
	for i in pairs(bountyCart) do	if toNil(i) then mBlock=true break end end

	return mw.html.create()
		:wikitext(eBlock and  "'''Противники:'''<br/>" or '')
			:node(table.concat(enemyCart,'<br/>'))
			:node(eBlock and  '<br/>' or nil)
		:wikitext(mBlock and  "'''Миссии:'''<br/>" or nil)
			:node(mCart)
		:wikitext(cBlock and  "'''Контейнеры:'''<br/>" or nil)
			:node(table.concat(containerCart,'<br/>'))
			:node(cBlock and  '<br/>' or nil)
		:allDone()
end

function p.dropTest(frame)
	targetName=targetName or frame.args[1] 
	
	
	if not DropLocs then
		DropLocs = {}
		for sName, Source in pairs(DropData) do
		if type(Source.MissionDrops)=="table" then
			for rotation, DT in Shared.ordpairs(Source.MissionDrops,{'Награда','A','B','C'}) do
				for _, Drop in pairs(DT) do
					if Drop.Name == targetName then
						
						if DropLocs[#DropLocs] ~= sName then 
							table.insert(DropLocs,sName)
						end
					end
				end
			end
		elseif type(Source.BountyDrops)=="table" then
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if Drop.Name == targetName then
							
							if DropLocs[#DropLocs] ~= sName then 
								table.insert(DropLocs,sName)
							end
						end
					end
				end
			end
		end
	end
		
	end
	
	local cart={}
	local alowedTiers={}
	local tiersHere ={}
	
	local function insInTier(tier,ident,rot,chance)
	--	if not alowedTiers[tier] then alowedTiers[tier]=true end
		if not tiersHere[tier] then tiersHere[tier]={} end
		table.insert(tiersHere[tier],{ident,rot,chance}) --..'%'
	end
	
	for j, sName in Shared.skpairs(DropLocs) do
		local Source = DropData[sName]
		if type(Source.MissionDrops)=='table' then
			for Rotation, DT in Shared.ordpairs(Source.MissionDrops,{'Награда','A','B','C'}) do
			for _, Drop in pairs(DT) do
				if Drop.Name == targetName then
					if type(Source.Tier)=='table' then
						for _,t in pairs(Source.Tier) do insInTier(t,sName,Rotation,Drop.Chance) end
						else insInTier((Source.Tier or sName),sName,Rotation,Drop.Chance)
					end
				end
			end
		end
		elseif type(Source.BountyDrops)=='table' then
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if Drop.Name == targetName then
							insInTier((Source.Tier or sName),sName,tier,Drop.Chance)
						end
					end
				end
			end
		end
	end
	local function excluciveAd(tabl,key)
		local addedIn={}
		local cart={}
		for _, stack in pairs(tabl) do
			if not addedIn[stack[key]] then 
				table.insert(cart,stack[key])
				addedIn[stack[key]]=true
			end
		end
		return cart
	end
	
	local function hignestVal(tabl,key)
		local king = 0
		for _, stack in pairs(tabl) do
			if toNil(stack[key]) and tonumber(stack[key]) > king then king = tonumber(stack[key]) end
		end
		return king
	end
	
	local tierStack={}
	
	for id, Mission in pairs(MissionData.MissionDetails) do
		if tiersHere[Mission.Tier] then
			if not tierStack[Mission.Tier] then tierStack[Mission.Tier]={} end
			table.insert(tierStack[Mission.Tier],id)
		end
	end
	
	local fin = mw.html.create('table'):attr('class','wikitable sortable')
			:tag('th'):wikitext('Режим'):done()
			:tag('th'):wikitext('Категория'):done()
			:tag('th'):wikitext('Ротации'):done()
			:tag('th'):wikitext('Шанс'):done():done()

	local function insType(Tier)
		--получает порядковый номер MissionData.MissionDetails с подходящей ротацией
		if tierStack[Tier] and tierStack[Tier][1] and MissionData.MissionDetails[tierStack[Tier][1]] then
			return '[['..(missionType(MissionData.MissionDetails[tierStack[Tier][1]]) or '')..']]'
		else return Tier end
	end
	
	for Tier, tData in Shared.skpairs(tiersHere) do
		local planets=''
		if type(tierStack[Tier])=='table' then
		for _,id in pairs(tierStack[Tier]) do
			if MissionData.MissionDetails[id] then
				planets=planets..MissionData.MissionDetails[id].Node..', '..MissionData.MissionDetails[id].Planet..'<br>'
			else
				
			end
		end
		end
		
		--сортировка ротаций и шансов
		local rotChances = {}
		local rotStack={}
		local chanceStack={}
		for _, Drop in pairs(tData) do
			if not rotChances[Drop[2]] then rotChances[Drop[2]] = {} end
			if not Shared.contains(rotChances[Drop[2]],Drop[3]) then table.insert(rotChances[Drop[2]],Drop[3]) end
		end
		for rotName, Chances in Shared.ordpairs(rotChances,rotationOrder) do
			--mw.log(rotName,table.concat(Chances,'/')..'%')
			
			local sum = 0
				for _,num in pairs(Chances) do
					sum = sum + (tonumber(num) or 0)
				end
			
			table.insert(rotStack,rotName)
			if rotName:find('Этап') then
				local nope = #Chances < 2
				if not nope then 
					sum=Shared.round(sum/#Chances, 2)
					for _, val in pairs(Chances) do
						if math.abs(val-sum) > 2.5 then nope = true break end
					end
					end
				if nope then table.insert(chanceStack,table.concat(Chances,'/')..'%')
				else -- упрощает отображение при незначительной разнице
					local s=mw.html.create('span'):addClass('acronymTooltip text-tooltip')
						:attr('data-param',table.concat(Chances,'%<br>')..'%')
						:wikitext('~'..sum..'%')
					table.insert(chanceStack,(mw.ustring.gsub(tostring(s),'&amp;','&')))
				end
				
			else 
				table.insert(chanceStack,sum..'%')
			end
			--mw.log(rotName, chanceStack[#chanceStack])
		end
		rotStack=table.concat(rotStack,', ')
		chanceStack=table.concat(chanceStack,', ')
		
		fin:tag('tr')
			--:tag('td'):done()
			:tag('td'):wikitext(insType(Tier)):done()
			:tag('td')
				:tag('span'):addClass('acronymTooltip text-tooltip')
					:attr('data-param',planets)
					:wikitext(DropData[tData[1][1]].Link or "МиссияМиссия")
				:done()
			:done()
			:tag('td'):wikitext(rotStack):done() --(table.concat(excluciveAd(tData,2),', ')):done()
			:tag('td'):wikitext(chanceStack):attr('data-sort-value',hignestVal(tData,3)):done() --(table.concat(excluciveAd(tData,3),', ')):done()
		:done()
	end

	
	return fin:allDone()

	
end



--проходит единожды по базе данных и ищет все выпадаемые реликвии
function p.everyRelic(frame)
	local stack ={}
	local targetTier = toNil(frame.args[1]) or "Нео"
	local targetFunction = toNil(frame.args[2]) or "relicEraDropLocations"
	local isRelic = {['Релик']=true,['Нетронутая']=true,['Необычная']=true, ['Бесподобная']=true, ['Сияющая']=true}
	for sName, Source in pairs(DropData) do
		if type(Source.MissionDrops)=="table" then
			for rotation, DT in Shared.ordpairs(Source.MissionDrops,{'Награда','A','B','C'}) do
				for _, Drop in pairs(DT) do
					if isRelic[Drop.Type] and Drop.Tier == targetTier then
						if not stack[Drop.Name] then stack[Drop.Name]={} end
						if stack[Drop.Name][#stack[Drop.Name]] ~= sName then 
							table.insert(stack[Drop.Name],sName)
						end
					end
				end
			end
		elseif type(Source.BountyDrops)=="table" then
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if isRelic[Drop.Type] and Drop.Tier == targetTier then
							if not stack[Drop.Name] then stack[Drop.Name]={} end
							if stack[Drop.Name][#stack[Drop.Name]] ~= sName then 
								table.insert(stack[Drop.Name],sName)
							end
						end
					end
				end
			end
		end
	end
	
	local function tabCreate(tabName,stuff)
		return mw.html.create('div')
	end
	
	local toEn = {['Лит'] = 'Lith',	['Мезо'] = 'Meso',	['Нео'] = 'Neo',['Акси'] = 'Axi'}
	
	exHead = mw.html.create('div'):attr('class','tabberex-head')
			:attr('data-tabber-id','relicsDrops'..(toEn[targetTier] or ''))
	exBody = mw.html.create('div'):attr('class','tabberex-body')
			:attr('data-tabber-id','relicsDrops'..(toEn[targetTier] or ''))
	
	
		for Name, DropLocs in Shared.skpairs(stack) do
			exHead:tag('div'):attr('class','tabberex-tab')
				  :attr('data-tab-header',Name):done()
			exBody:tag('div'):tag('div')
			:node(p[targetFunction]({},targetTier,Name,DropLocs)):done()
		end

	return mw.html.create():node(exHead):node(exBody)
end

function p.relicEraDropLocations(frame,targetTier,targetName,DropLocs)
	targetName=targetName or frame.args[2] 
	targetTier=targetTier or frame.args[1]
	
	if not DropLocs then
		DropLocs = {}
		local isRelic = {['Релик']=true,['Нетронутая']=true,['Необычная']=true, ['Бесподобная']=true, ['Сияющая']=true, ['Реквием']=true}
		for sName, Source in pairs(DropData) do
		if type(Source.MissionDrops)=="table" then
			for rotation, DT in Shared.ordpairs(Source.MissionDrops,{'Награда','A','B','C'}) do
				for _, Drop in pairs(DT) do
					if isRelic[Drop.Type] and Drop.Name == targetName and Drop.Tier == targetTier then
						
						if DropLocs[#DropLocs] ~= sName then 
							table.insert(DropLocs,sName)
						end
					end
				end
			end
		elseif type(Source.BountyDrops)=="table" then
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if isRelic[Drop.Type] and Drop.Name == targetName and Drop.Tier == targetTier then
							
							if DropLocs[#DropLocs] ~= sName then 
								table.insert(DropLocs,sName)
							end
						end
					end
				end
			end
		elseif type(Source.Relics)=="table" then
			for _, Relic in pairs(Source.Relics) do
				if isRelic[Relic.Type] and Relic.Name == targetName and Relic.Tier == targetTier then
					if DropLocs[#DropLocs] ~= sName then 
						table.insert(DropLocs,sName)
					end
				end
			end
		end
	end
		
	end
	DropLocs = DropLocs or {}
		
	
	local cart={}
	local alowedTiers={}
	local tiersHere ={}
	
	local function insInTier(tier,ident,rot,chance)
	--	if not alowedTiers[tier] then alowedTiers[tier]=true end
		if not tiersHere[tier] then tiersHere[tier]={} end
		table.insert(tiersHere[tier],{ident,rot,chance}) --..'%'
	end
	
	for j, sName in Shared.skpairs(DropLocs) do
		local Source = DropData[sName]
		if type(Source.MissionDrops)=='table' then
			for Rotation, DT in Shared.ordpairs(Source.MissionDrops,{'Награда','A','B','C'}) do
			for _, Drop in pairs(DT) do
				if Drop.Name == targetName and Drop.Tier == targetTier then
					if type(Source.Tier)=='table' then
						for _,t in pairs(Source.Tier) do insInTier(t,sName,Rotation,Drop.Chance) end
						else insInTier((Source.Tier or sName),sName,Rotation,Drop.Chance)
					end
				end
			end
		end
		elseif type(Source.BountyDrops)=='table' then
			for vName, Variant in pairs(Source.BountyDrops) do
				for tier, DT in pairs(Variant)	do
					for _, Drop in pairs(DT) do
						if Drop.Name == targetName and Drop.Tier == targetTier then
							insInTier((Source.Tier or sName),sName,tier,Drop.Chance)
						end
					end
				end
			end
		end
	end
	
	local function excluciveAd(tabl,key)
		local addedIn={}
		local cart={}
		for _, stack in pairs(tabl) do
			if not addedIn[stack[key]] then 
				table.insert(cart,stack[key])
				addedIn[stack[key]]=true
			end
		end
		return cart
	end
	
	local function hignestVal(tabl,key)
		local king = 0
		for _, stack in pairs(tabl) do
			if toNil(stack[key]) and tonumber(stack[key]) > king then king = tonumber(stack[key]) end
		end
		return king
	end
	
	local tierStack={}
	
	for id, Mission in pairs(MissionData.MissionDetails) do
		if tiersHere[Mission.Tier] then
			if not tierStack[Mission.Tier] then tierStack[Mission.Tier]={} end
			table.insert(tierStack[Mission.Tier],id)
		end
	end
	
	local fin = mw.html.create('table'):attr('class','wikitable sortable')
			:tag('th'):wikitext('Режим'):done()
			:tag('th'):wikitext('Категория'):done()
			:tag('th'):wikitext('Ротации'):done()
			:tag('th'):wikitext('Шанс'):done():done()

	local function insType(Tier)
		--получает порядковый номер MissionData.MissionDetails с подходящей ротацией
		if tierStack[Tier] and tierStack[Tier][1] and MissionData.MissionDetails[tierStack[Tier][1]] then
			return '[['..(missionType(MissionData.MissionDetails[tierStack[Tier][1]]) or '')..']]'
		else return Tier end
	end
	
	for Tier, tData in Shared.skpairs(tiersHere) do
		local planets=''
		if type(tierStack[Tier])=='table' then
		for _,id in pairs(tierStack[Tier]) do
			if MissionData.MissionDetails[id] then
				planets=planets..MissionData.MissionDetails[id].Node..', '..MissionData.MissionDetails[id].Planet..'<br>'
			else
				
			end
		end
		end
		
		--сортировка ротаций и шансов
		local rotChances = {}
		local rotStack={}
		local chanceStack={}
		for _, Drop in pairs(tData) do
			if not rotChances[Drop[2]] then rotChances[Drop[2]] = {} end
			if not Shared.contains(rotChances[Drop[2]],Drop[3]) then table.insert(rotChances[Drop[2]],Drop[3]) end
		end
		for rotName, Chances in Shared.ordpairs(rotChances,rotationOrder) do
			table.insert(rotStack,rotName)
			table.insert(chanceStack,table.concat(Chances,'/')..'%')
		end
		rotStack=table.concat(rotStack,', ')
		chanceStack=table.concat(chanceStack,', ')
		
		fin:tag('tr')
			--:tag('td'):done()
			:tag('td'):wikitext(insType(Tier)):done()
			:tag('td')
				:tag('span'):addClass('acronymTooltip text-tooltip')
					:attr('data-param',planets)
					:wikitext(DropData[tData[1][1]].Link or "МиссияМиссия")
				:done()
			:done()
			:tag('td'):wikitext(rotStack):done() --(table.concat(excluciveAd(tData,2),', ')):done()
			:tag('td'):wikitext(chanceStack):attr('data-sort-value',hignestVal(tData,3)):done() --(table.concat(excluciveAd(tData,3),', ')):done()
		:done()
	end

	
	return fin:allDone()

	
end


---	Gets the list of missions that give rewards for a specific Alias (ex Defense1)
--	@function		p.getMissionTable
function p.getMissionTable(MissionAlias)
    local data = {}
    for _, m in Shared.skpairs(MissionData["MissionDetails"]) do
        if(m.Tier == MissionAlias) then
            table.insert(data, m)
        end
    end
    return data
end

function toNil(thing)
	if thing==nil or thing=="" then return nil else return thing end
end

--вставляет в переданную таблицу строку корректного форматирования с дропом
function insertDrop(cart,Drop,Source,chanceField)
	
	local chance = ((Source[chanceField] or 100) /100 *(Drop.Chance or 0))
	if chance == 0 then return cart else chance = ' ('..Shared.round(chance,2,2)..'%)' end
	
	table.insert(cart,drawDrop(Drop)..chance)
	
	return cart
end

--возвращает строку с корректным названием ротации
function rotName(genName,customName)
		local abcRotations={A=true,B=true,C=true,a=true,b=true,c=true}
		if customName then return customName end
		if tonumber(genName) then 
			return 'Награда' 
		elseif abcRotations[genName] then 
			return 'Ротация '..genName
		else 
			return genName
		end
end

function regionName(Source,Regions)
	Regions = Regions or {}
	local rl =''
	if 	Source.RegLink==false then rl=Source.Region
	else rl='[['..(Source.RegLink or Source.Region)..'|'..Source.Region..']]'	end
	if Source.RegSuffix then rl = rl..' '..Source.RegSuffix end
	return '<span class="acronymTooltip text-tooltip" data-param="'..table.concat(Regions,'<br>')..'">'..regionName..'</span>'
	
end

--возвращает строку с источником дропа корректного форматирования
function insertSource(cart,Drop,Source,sName,rootChance,noLink)
	local chance = ((rootChance or Source[cTarget[Drop.Type]] or 100) /100 *(Drop.Chance or 0))
	
	if chance == 0 then return cart else chance = Shared.round(chance,2,2) end
	if noLink==true then 	
		table.insert(cart, sName..': '..chance..'%'..(Drop.Q and ', '..Drop.Q..'шт' or ''))--вариант для тултипов
		else
		table.insert(cart,'[['..(toNil(Source.Link) or sName)..'|'..(Source.Name or sName)..']] ('..chance..'%)'..(Drop.Q and ', '..Drop.Q..'шт' or ''))
	end
	return cart
end

function insertMission(cart,Drop,Source,sName,rotation)
	table.insert(cart,'[['..(toNil(Source.Link) or sName)..'|'..(Source.Name or sName)..']] - '..rotation..' ('..Drop.Chance..'%)')
	return cart
end

--возвращзает заглушку мода, если мод не найден в Мод/Данные
function modPH(ModName)
	 return tostring(mw.html.create('span')
		:attr('title',"Мод '"..ModName.."' не распознан. Название чувствительно к регистру знаков и букве Ё")
		:attr('style','border-bottom: 1px dashed grey; padding-bottom: 0.8px; cursor: help;')
		:tag('font'):attr('color','grey'):wikitext('(?) '):done()
		:wikitext('[['..(ModName)..']]'))
end

--возвращает список дропов запрошенного противника
function p.dropEnemy(frame)
	local sourceName = frame.args[1]
	local sCart = {}
	
	if DropData[sourceName] and type(DropData[sourceName])=='table' and not DropData[sourceName].Exclude then
		local Source=DropData[sourceName]
		--ищет таблицы с дропом
		for droptable, label in pairs({ModDrops="Моды", itemsBps="Предметы", extraItems="Доп. предметы",
										Resources="Ресурсы", Sigils="Дополнительно", Relics="Реликвии",}) do
			if Source[droptable] then
				table.insert(sCart, '<b>'..label..':</b>')
				for _, Drop in pairs(Source[droptable]) do
					sCart = insertDrop(sCart,Drop,Source,chanceField[droptable])
				end
				--table.insert(sCart, '\n')
			end
		end
	end
		--для боссов выводит награду за прохождение миссии, ищет миссии  'Убийство/Название Босса'
	if DropData['Убийство/'..sourceName] and type(DropData['Убийство/'..sourceName].MissionDrops) == 'table' 
		and not DropData['Убийство/'..sourceName].Exclude then
			
		local missionSource = DropData['Убийство/'..sourceName]
		
		--ищет планету миссии с указанным тиром для боссов как
		--Лейтенант Лех Крил, которий присутствует на нескольких планетах
		for _, Mission in pairs(MissionData.MissionDetails) do
			localMissionName = (Mission.Tier == missionSource.Tier and Mission.Planet) or localMissionName
		end
		
		table.insert(sCart, '<b>Награда за миссию ('..(localMissionName or missionSource.Tier)..'):</b>')
		for _, Drop in pairs(missionSource.MissionDrops['Награда']) do
			sCart = insertDrop(sCart,Drop,missionSource)
		end
	end
	
	return table.concat(sCart,'<br>')
end

--возвращает таблицу дропов запрошенного заказа
function p.printBountyTable(frame)
	local targetName = frame.args[1]
	local stagesStack = {}
	local tableMaxn= {}
	local passCount = 0
	local cart = mw.html.create()
	local header=mw.html.create('tr')
	local tableTitles={'Вариант A','Вариант B','Вариант C','Вариант D'}
	
	if DropData[targetName] then
	if type(DropData[targetName].BountyDrops)=='table' then
		local BountyDrops=DropData[targetName].BountyDrops
		
		for vName, Variant in pairs(BountyDrops) do
			passCount=passCount+1
			header:tag('th'):attr('colspan','2'):wikitext(tableTitles[vName]):done()
			for stageName, Drops in Shared.ordpairs(Variant,rotationOrder) do
				tableMaxn[stageName]=tableMaxn[stageName] or 0
				local counted = Shared.tableCount(Drops)
				if counted > tableMaxn[stageName] then tableMaxn[stageName] = counted end
				if passCount==1 then 
					table.insert(stagesStack,stageName)
				end
			end
		end
	
	for _, stageName in pairs(stagesStack) do
		local aTable=mw.html.create('table')
			:attr('class','emodtable')
			:addClass('dropTableWith'..Shared.tableCount(BountyDrops)..'cols')
			:node(header)
		for i=1, tableMaxn[stageName] do
			local row=mw.html.create('tr')
			for vName in pairs(BountyDrops) do
				if BountyDrops[vName][stageName][i] then
				row:tag('td'):wikitext(drawDrop(BountyDrops[vName][stageName][i])):done()
				   :tag('td'):wikitext(BountyDrops[vName][stageName][i].Chance..'%'):done()
				   else	row:tag('td'):attr('colspan',2):done()
				end
			end
			aTable:node(row)
		end
		cart:tag('center'):tag('h3'):wikitext(stageName):done():done()
			:node(aTable)
	end

	else return 'Отсутствуют BountyDrops'end
	else return 'Объект '..targetName..' не найден [[Категория:Маячок]]'	end
	
	return cart:newline():wikitext(p.listLocations(DropData[targetName].Tier))
end
	
--возвращает таблицу дропов запрошенной миссии
function p.printMissionTable(frame)
	local targetName = frame.args[1]
	local skipLocations = toNil(frame.args[2])
	local colNames = {}
	local tableMaxn=0
	local aTable=mw.html.create('table'):attr('class','emodtable')
	
	if DropData[targetName] then
	if type(DropData[targetName].MissionDrops)=='table' then
		local MissionDrops=DropData[targetName].MissionDrops
		local header=mw.html.create('tr')
		for tableName, dT in Shared.ordpairs(MissionDrops,rotationOrder)	do
			local counted = Shared.tableCount(dT)
			if counted>tableMaxn then tableMaxn=counted end
			table.insert(colNames,tableName)
			header:tag('th'):attr('colspan','2'):wikitext(rotName(tableName)):done()
		end
		aTable:node(header)
		aTable:addClass('dropTableWith'..#colNames..'cols')
		
		for i=1, tableMaxn do
			 local trC=mw.html.create('tr')
			for _, colName in pairs(colNames) do
				if MissionDrops[colName][i] then
				trC:tag('td'):wikitext(drawDrop(MissionDrops[colName][i])):done()
				   :tag('td'):wikitext(MissionDrops[colName][i].Chance..'%'):done()
				   else	trC:tag('td'):attr('colspan',2):done()end
			end
			aTable:node(trC)
		end 
	
	else return 'Отсутствуют MissionDrops'end
	else return 'Объект '..targetName..' не найден'	end
	
	return mw.html.create():node(aTable):newline():wikitext(skipLocations and '' or p.listLocations(DropData[targetName].Tier))
end

--Возвращает список миссий (Модуль:Миссия/Данные) по запрошеному Tier
function p.listLocations(loc)
	local dropLoc ={}
	local locIndex={}
	local pCart=''
	if not toNil(loc) then return '' end
	
	if type(loc)=='table' then
		for i,Location in pairs(loc) do
			locIndex[Location]=true
		end
	else
		locIndex[loc]=true
	end
	
	for _, Mission in pairs(MissionData.MissionDetails) do
		if not Mission.IgnoreInList and locIndex[Mission.Tier] then
			if not dropLoc[Mission.Planet] then dropLoc[Mission.Planet]={} end
			table.insert(dropLoc[Mission.Planet],Mission.Node)
		end
	end
	for Planet, MissionList in Shared.ordpairs(dropLoc,{'Земля','Венера','Меркурий','Марс','Фобос','Деймос','Церера','Юпитер','Европа','Сатурн','Уран','Нептун','Плутон','Эрида','Седна','Бездна','Луа','Крепость Кувы'}) do
		for _, Node in pairs(MissionList) do
			pCart=pCart.."\n*"..Node..', [['..Planet..']]'
		end
	end
	
	if toNil(pCart) then pCart= ":'''Локации:'''"..pCart end
	return pCart
end

--возвращает запрошенный дроп с корректным форматированием
function drawDrop(Drop)
	local skipQ=false
	
	--добавляет "Чертёж", использовать только при отображении
	local function disName(Drop)
		if Drop.isBP then return "Чертёж: "..(Drop.Name or "") else return Drop.Name end
	end
	
	local function planB(Drop)
		return '[['..(toNil(Drop.Link) or Drop.Name or'')..'|'..(disName(Drop) or '')..']]'	
	end
	
	local D ={}
	function D.Mod(Drop)
		local Mod = Mods.getMod(Drop.Name)
		if type(Mod)=='table' then
			return Mods.modString(Drop.Name, nil, Mod)
		else
			return cart,modPH(Drop.Name)
		end
	end
	function D.Item(Drop)
		local Item=Icons.getIcon(Drop.Name,{Link=Drop.Link})
		return Icons.Main(Item,disName(Drop),22,Drop.Q and Shared.formatnum(Drop.Q))
	end
	function D.Relic(Drop)
		if Relics.getRelic(Drop.Tier,Drop.Name) then
			if Drop.Type == "Релик" then return tostring(Relics.relicCell(Drop.Tier,Drop.Name,Drop.Type,nil,22))
			else return tostring(Relics.relicCell(Drop.Tier,Drop.Name,Drop.Type,22))..' ('..Drop.Type..')' end
		else return planB(Drop) end	
	end
	function D.Part(Drop)
		local Item=Icons.getIcon(Drop.Name,{Link=Drop.Link, Icon=Drop.Icon})
		local displayName = ''
		if Drop.isBP then displayName ='Чертёж: 'end
		if Drop.Link then displayName = displayName..Drop.Link..': ' end	
		displayName = displayName..Drop.Name
		return Icons.Main(Item,displayName,22,Drop.Q)
	end
	function D.Common(Drop)
		return planB(Drop)
	end

	local Reg={
		['Мод']='Mod',
		['Эндо']='Item', ['Предмет']='Item', ['Мистификатор']='Item',
		['Релик']='Relic',['Нетронутая']='Relic',['Необычная']='Relic', ['Бесподобная']='Relic', ['Сияющая']='Relic',
		['Часть']='Part',
	}
	
	local drawnDrop
	drawnDrop = D[Reg[Drop.Type] or 'Common'](Drop)

	--if Drop.Q and skipQ~=true then drawnDrop=Drop.Q..' '..drawnDrop end
	return drawnDrop or ''
end


return p