此模块的文档可以在模块:Home/level/doc创建

local Util = require('Module:Util')
local Name = require('Module:Const/name')
local ItemLink = require('Module:Item').link
local ItemData = require('Module:Item/data')
local HomeShopEventTyp = require('Module:Home/shopEventTyp/data')
local HomeShopEvent = require('Module:Home/shopEvent/data')

local function GetShopEvent(place)
	local eventTypId = tonumber(place[96])
	if eventTypId==0 then return nil end

	local eventLists = {}
	local eventTyp = HomeShopEventTyp[eventTypId]
	for i,score in ipairs{1,2,-1,-2} do --不同评价
		local eventIds = eventTyp[i] --相同评价的多个事件,会随机触发一个
		if (type(eventIds)~='table') then error(mw.dumpObject(eventTyp)) end
		local eventList = {}
		for j,eventId in ipairs(eventIds) do
			local event = HomeShopEvent[eventId]
			eventList[j] = event
		end
		eventLists[i] = {score, eventList}
	end
	return eventLists
end

local function Factorial(n) --阶乘
	local result = 1
	for i=2,n do
		result = result * i
	end
	return result
end

local function C(n,m) --组合情况
	return Factorial(n)/Factorial(m)/Factorial(n-m)
end

local function Binomial(n,p,k) --二项分布
	return C(n,k) * p^k * (1-p)^(n-k)
end

local function ShowPercent(v) --百分比显示
	local v0 = Util.toInt(v*10000)
	if v0>0 then
		return (v0/100)..'%'
	else
		local v1 = math.floor(1/v)
		if v1>1000 then
			v1 = string.format("%.1E",v1)
		end
		return '1/'..v1
	end
end

local function Income(eventList, level)
	local result = {}
	for _, event in ipairs(eventList) do
		local group = {}
		for i,typ in ipairs(event[11]) do
			local id = event[12][i]
			local amount = event[13][i]
			local baseBonus = event[15][i]
			local line = ''
			if typ == 1 then
				line = mw.getCurrentFrame():expandTemplate{
					title = '资源',
					args = {id, '0~'..math.floor(amount * (80+level*8) / 100 * 2)}
				}
			elseif typ == 2 then
				--baseBonus为抽奖次数
				local chance = baseBonus*2 + math.floor(baseBonus*level/3) --中奖概率
				chance = math.min(chance,60)/100
				for addLevel = baseBonus,0,-1 do
					local text = ' '..ShowPercent(Binomial(baseBonus,chance,addLevel))
					local itemIdList = mw.text.split(id,'&',true)
					if #itemIdList > 3 then --数量太多影响排版,省略
						local firstItem = ItemData[itemIdList[1] + addLevel]
						local typName = Name.item[firstItem[5]]
						text = ItemLink(firstItem)..'等'..#itemIdList..'种'..typName..text
					else
						local list = {}
						for j,itemId in ipairs(itemIdList) do
							list[j] = ItemLink(ItemData[itemId + addLevel])
						end
						text = table.concat(list, '、')..text
					end
					if line~='' then line = line..'<br/>' end
					line = line..text
				end
			elseif typ == 3 then
				local min = baseBonus + level
				local max = baseBonus + level*3
				line = '流民单项资质'..Util.color(min, 'white')..'~'..Util.color(max, 'white')
			elseif typ == 4 then --福人居
				local chance = math.floor(baseBonus/2) + math.floor(baseBonus*level/6)
				chance = math.min(chance,90)/100
				local chanceSum = {}
				for bonus = 0,baseBonus do
					local ququLevel = Util.clamp(math.floor(bonus/3),1,9)
					chanceSum[ququLevel] = (chanceSum[ququLevel] or 0) + Binomial(baseBonus,chance,bonus)
					--mw.log(bonus, baseBonus, chance, Binomial(baseBonus,chance,bonus))
				end
				for ququLevel=#chanceSum,1,-1 do
					if line~='' then line = line..'<br/>' end
					local ququName = Name.ququ[ququLevel]
					ququName = mw.text.split(ququName,'·',true)[1]
					line = line..Util.color(ququName, Name.color[ququLevel])
						.. ' ' .. ShowPercent(chanceSum[ququLevel])
				end
			else
				line = '一无所获'
			end
			table.insert(group, line)
		end
		table.insert(result, table.concat(group, '<br />'))
	end
	return table.concat(result, '<div style="border-bottom:1px dashed #fff;margin:5px 20px"></div>')
end

local function Incomes(eventLists, level)
	local h = mw.html.create('ul'):addClass('income')
	for _, order in ipairs{2,1,3,4} do
		local pair = eventLists[order]
		local score = pair[1]
		local eventList = Income(pair[2], level)
		local mark = '&#61;&#61;&#61;' -- ===
		h:tag('li'):wikitext(mark..' '..string.format('%+d', score)..'评价 '..mark)
		h:tag('li'):wikitext(eventList)
	end
	return h
end

local function tt(title, content)
	return '<span class="tooltip1" style="border-bottom:1px dotted;">'..title..' <span class="tooltiptext">'..content..'</span></span>'
end

return function(frame) -- p('仓库')
	local place = frame.getParent and frame:getParent().args or require('Module:Home/data/one')(frame)._source
	place = require('Module:ParseData').one(place)
	if tonumber(place[2])~=1 then return '' end
	local maxLevel = tonumber(place[1])
	local bonus = tonumber(place[18])
	local o = {}
	do
		local dataList = {}
		for level=1,maxLevel do
			dataList[level] = {}
		end
		local h = mw.html.create('table'):addClass('wikitable')
		local headRow = h:tag('tr')
		local contentRow = h:tag('tr')

		local cnt = 0

		function o.add(head, getContent)
			headRow:tag('th'):wikitext(head)
			cnt = cnt + 1
			local varName = 'v'..cnt
			contentRow:tag('td'):attr('data-v-html', varName) --mw解析器会把大部分attr过滤掉,只能存在data-中,到时候用jQuery预处理
			for level=1,maxLevel do
				dataList[level][varName] = getContent(level, place)
			end
		end

		function o.appearance()
			return tostring(h)
		end

		function o.data()
			local result = mw.html.create('ol'):addClass('data-list'):css('display', 'none')
			for level=1,maxLevel do
				local li = result:tag('li')
				for k,v in pairs(dataList[level]) do
					li:tag('div'):attr('data-key', k):wikitext(v)
				end
			end
			return tostring(result)
		end
	end

	local need = {}
	local sum = {}
	do
		local base = {}
		for j=1,7 do
			base[j] = place[j+10]
		end
		need[1] = base
		sum[1] = base
		for level=2,maxLevel do
			need[level] = {}
			sum[level] = {}
			for i=1,7 do
				need[level][i] = math.floor(base[i] * (100 + bonus*(level-1)) / 1000) * 10
				sum[level][i] = sum[level-1][i] + need[level][i]
			end
		end
		local frame = mw.getCurrentFrame()
		for level=1,maxLevel do
			need[level] = frame:expandTemplate{ title = '资源列表', args = need[level]}
			sum[level] = frame:expandTemplate{ title = '资源列表', args = sum[level]}
		end
	end
	if maxLevel==1 then
		o.add('建造消耗', function(level) return need[level] end)
	else
		o.add('升级消耗', function(level) return need[level] end)
		o.add('累计消耗', function(level) return sum[level] end)
	end

	local eventLists = GetShopEvent(place)
	if eventLists then
		o.add(
			tt('经营收益','数字中E为[https://baike.baidu.com/item/科学记数法 科学记数法],如1/3E+02表示300分之1'),
			function(i) return tostring(Incomes(eventLists, i)) end
		)
		o.add('技艺需求',function(i, place) return (Name.skill[tonumber(place[33])] or '名誉')..'<br />'..Util.color(place[51]+i-1, 'white') end)
	end
	if tonumber(place[66])>0 then
		o.add(tt('修习历练消耗', '最低降至25%'), function(i) return '-'..(i*5)..'%' end)
	end
	if tonumber(place[67])>0 then
		o.add(tt('突破历练消耗', '最低降至25%'), function(i) return '-'..(i*5)..'%' end)
	end
	if tonumber(place[84])>0 then --方略室
		o.add('同道上限', function(i) return '+'..(2 + math.floor(i/4)) end)
	end
	if tonumber(place[81])>0 then --藏书阁
		o.add('[[交换藏书#购买藏书|交换藏书消耗系数]]', function(i) return '-'..(25 + i*3)..'%' end)
	end
	if tonumber(place[70])>0 then --阅经阁
		o.add('研读耐心', function(i) return '+'..(i*5) end)
	end
	if tonumber(place[61])>0 then --居所
		o.add('人力', function(i) return '+'..(i+1) end)
	end
	if tonumber(place[6])>0 then --采集
		o.add('资源点增长机率', function(i, place) return '+'..(i*place[6]+3)..'%' end)
	end
	if tonumber(place[80])>0 then --降造诣
		o.add('造诣需求', function(i) return '-'..(i*2) end)
	end
	if tonumber(place[63])>0 then --仓库
		o.add(tt('物品容量','基础值为200'), function(i) return '+'..(i*20) end)
		o.add(tt('资源容量','基础值为 来自人物1000 + 来自仓库400'), function(i) return '+'..(i*1500) end)
	end


	local result =  o.appearance()..'\n'..o.data()
	--mw.log(result)
	return result
end
avatar