Module:Sandbox/User:Artoire/1: Difference between revisions

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
mNo edit summary
mNo edit summary
Line 1:
--[[
mw.log(p._main{
current_xp = 24,
target_xp = 37,
ingot = 'Maloic Adathril Ingot',
})
]]
 
require('strict')
local persistant = require('Module:Break Isolation')Mw.get_module_store('Module:Locationhtml Tableextension')
local parsexp = require('Module:Param ParseExperience')
local editcache = 'Unknown <span class="small plainlinks">' .. require('Module:EditBreak buttonIsolation').get_module_store() .. '<Module:Sandbox/span>User:Artoire/1')
local currency = require('Module:Currency')
local lang = mw.language.getContentLanguage()
 
local function lookup_ingots()
persistant.counter = persistant.counter or 0
if cache.ingots then return cache.ingots end
local ingots = {
recipes = {},
order = {}
}
cache.ingots = ingots
for _, result in ipairs(mw.smw.ask{
'[[Uses facility::Goblin Smelter||Gnome Smelter]]',
['?Recipe JSON'] = '',
mainlabel = '-',
sort = 'Profession Level A',
limit = '500'
}) do
result = mw.text.jsonDecode(result[1])
local ingot = result.output[1].name
ingots.recipes[ingot] = {
xp = result.xp,
facility = result.facility,
ingot = result.output[1].name,
ore = result.materials[1].name,
level = result.level
}
table.insert(ingots.order, ingot)
end
return ingots
end
 
local pfunction = {}lookup_weapons()
if cache.weapons then return cache.weapons end
 
local ingots = lookup_ingots()
function p.head(frame)
local argsweapons = frame.args{}
cache.weapons = weapons
assert(not persistant.in_table, 'Second {{LocTableHead}} (Missing {{LocTableBottom}}?)')
for _, result in ipairs(mw.smw.ask{
persistant.in_table = true
'[[Uses facility::Goblin Forge||Gnome Forge]]',
persistant.json = {}
['?Recipe JSON'] = '',
persistant.version = args.version
mainlabel = '-',
persistant.location_object = mw.title.getCurrentTitle().fullText
sort = 'Profession Level A',
if args.version then
limit = '500'
persistant.location_object = persistant.location_object .. '#' .. args.version
}) do
local lvl = result['Profession Level A']
result = mw.text.jsonDecode(result[1])
local ingot
local pole
for _, material in ipairs(result.materials) do
if ingots.recipes[material.name] then
assert(not ingot)
ingot = material
else
assert(not pole)
pole = material
end
end
weapons[ingot.name] = weapons[ingot.name] or {}
table.insert(weapons[ingot.name], {
facility = result.facility,
level = result.level,
ingot = ingot,
pole = pole,
name = result.output[1].name,
xp = result.xp
})
end
return weapons
end
 
local function p.line_lookup_price_uncached(frameitem)
local result = tonumber(mw.smw.ask{
assert(persistant.in_table, '{{LocLine}} when not in a location table (Missing {{LocTableHead}}?)')
('[[Sold item::%s]]'):format(item),
local args = frame.args
['?Shop buy price'] = '',
local loc = args.loc
mainlabel = '-'
local qty = args.quantity
}[1][1])
qty = tonumber(qty or '')
persistant.json[loc]return = qtyresult or -1
end
local loc_link = ('[[%s]]'):format(loc)
local episode = mw.smw.ask{loc_link, '?Episode#=', 'mainlabel=-'}
episode = episode and episode[1][1]
 
cache.lookup_price = cache.lookup_price or {}
persistant.counter = persistant.counter + 1
local function lookup_price(item)
local id = 'LOC_' .. persistant.counter
cache.lookup_price[item] = cache.lookup_price[item] or _lookup_price_uncached(item)
return cache.lookup_price[item]
end
 
local function _lookup_pole_uncached(pole)
mw.smw.subobject({
local pole_data = mw.text.jsonDecode(mw.smw.ask{
['Location object'] = persistant.location_object,
('[[%s]]'):format(pole),
['Located in'] = loc,
['Location?Recipe quantityJSON'] = qty or 'Unknown',
mainlabel = '-'
}, id)
}[1][1])
local post = pole_data.materials[1].name
local post_data = mw.text.jsonDecode(mw.smw.ask{
('[[%s]]'):format(post),
['?Recipe JSON'] = '',
mainlabel = '-'
}[1][1])
return {
level = pole_data.level,
pole = pole,
post = post,
log = post_data.materials[1].name
}
end
 
cache.lookup_pole = cache.lookup_pole or {}
return mw.html.create('tr')
local function lookup_pole(pole)
:attr{ id = id }
cache.lookup_pole[pole] = cache.lookup_pole[pole] or _lookup_pole_uncached(pole)
:tag('td'):wikitext(loc_link):done()
return cache.lookup_pole[pole]
:tag('td'):wikitext(parse.episode_func(episode)):done()
:tag('td'):wikitext(qty or edit):done()
:done()
end
 
local function p.bottom_lookup_ore_uncached(frameore)
local data = mw.smw.ask{
assert(persistant.in_table, '{{LocTableBottom}} when not in a location table (Missing {{LocTableHead}}?)')
('[[%s]]'):format(ore),
['?Profession Level A'] = '',
mainlabel = '-'
}[1]
return {
level = tonumber(data[1])
}
end
 
cache.lookup_ore = cache.lookup_ore or {}
if persistant.version then
local function lookup_ore(ore)
mw.smw.subobject({ ['Location JSON'] = mw.text.jsonEncode(persistant.json) }, persistant.version)
cache.lookup_ore[ore] = cache.lookup_ore[ore] or _lookup_ore_uncached(ore)
return cache.lookup_ore[ore]
end
 
local function _lookup_log_uncached(log)
local data = mw.smw.ask{
('[[%s]]'):format(ore),
['?Profession Level A'] = '',
mainlabel = '-'
}[1]
return {
level = tonumber(data[1])
}
end
 
cache.lookup_log = cache.lookup_log or {}
local function lookup_log(log)
cache.lookup_log[log] = cache.lookup_log[log] or _lookup_log_uncached(log)
return cache.lookup_log[log]
end
 
local p = {}
 
local p = {}
 
function p.ingots()
return table.concat(lookup_ingots().order, ',')
end
 
function p.main(frame)
return p._main(frame:getParent().args)
end
 
p.w = lookup_weapons
 
function p._main(args)
local current_xp = tonumber(args.current_xp) or 0
local current_lvl
if current_xp <= 500 then
current_lvl = current_xp
current_xp = xp._total_xp(current_lvl)
else
current_lvl = xp._level_at(current_xp)
mw.smw.set{ ['Location JSON'] = mw.text.jsonEncode(persistant.json) }
end
 
local target_xp = tonumber(args.target_xp) or 0
local target_lvl
if target_xp <= 500 then
target_lvl = target_xp
target_xp = xp._total_xp(target_lvl)
else
target_lvl = xp._level_at(target_xp)
end
 
local remaining_xp = target_xp - current_xp
 
local buying_poles = args.pole_buy
local chopping_logs = buying_poles == 'none'
local buying_logs = buying_poles == 'logs'
buying_poles = not (buying_logs or chopping_logs)
 
local ingot = lookup_ingots().recipes[args.ingot]
 
local result = mw.html.create()
 
result:wikitext(('To get from %s xp (level %s) to %s xp (level %s) requires %s experience'):format(current_xp, current_lvl, target_xp, target_lvl, remaining_xp))
 
local tbl = result:tag('table')
:addClass('wikitable sortable')
 
local function skillclickpic(profession)
return ('[[File:%s small icon.png|15px|link=%s|%s level]]'):format(profession, profession, profession)
end
local colspan = 24
if chopping_logs then
colspan = colspan + 4
end
if chopping_logs or buying_logs then
colspan = colspan + 1
end
 
tbl
:tr()
:th(skillclickpic('Miner')):done()
:th{ 'Ore', attr = { colspan = '3' } }:done()
:th(skillclickpic('Blacksmith')):done()
:th{ 'Ingot', attr = { colspan = '3' } }:done()
:IF(chopping_logs)
:th(skillclickpic('Woodcutter'))
:th{ 'Log', attr = { colspan = '3' } }:done()
:th()
:IF(chopping_logs or buying_logs)
:th(skillclickpic('Carpenter'))
:DONE()
:th{ 'Pole', attr = { colspan = '3' } }:done()
:th{ 'Product', attr = { colspan = '3' } }:done()
:th{ 'Cost', attr = { colspan = '10' } }:done()
:done()
 
for _, weapon in lookup_weapons()[ingot.name] do
if not ingot.xp then
tbl
:tr()
:td{
'Missing XP for smelting [[' .. ingot.name .. ']]; Please [' .. mw.uri.fullUrl(ingot.name, 'action=edit&section=1') .. ' edit the page] to add the experience earned (after |exp =)',
attr = { colspan = colspan }
}
:done()
break
end
if not weapon.xp then
tbl
:tr()
:td{
'Missing XP for creating [[' .. weapon.name .. ']]; Please ['.. mw.uri.fullUrl(weapon.name, 'action=edit&section=1') .. ' edit the page] to add the experience earned (after |exp =)',
attr = { colspan = colspan }
}
:done()
break
end
local xp_per = weapon.xp + ingot.xp * weapon.ingot.quantity
local needed = math.ceil(remaining_xp / xp_per)
 
local needed_ores = needed * weapon.ingot.quantity
local row = tbl
:tr()
:td(lookup_ore(ingot.ore).level)
:td{ needed_ores .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right', ['data-sort-value'] = needed_ores } }
:td{ ('[[File:%s.png|link=%s|30px]]'):format(ingot.ore), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
:td{ '[[' .. ingot.ore .. ']]', addClass = 'plinkt-link no-border' }
 
local pole_info
local needed_logs, needed_poles
 
if weapon.pole then
needed_poles = needed * weapon.pole.quantity
if chopping_logs then
pole_info = lookup_pole(weapon.pole.name)
needed_logs = math.ceil(needed_poles / 2)
row
:td(lookup_log(pole_info.log).level)
:td{ needed_logs .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed_logs } }
:td{ ('[[File:%s.png|link=%s|30px]]'):format(pole_info.log), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
:td{ '[[' .. pole_info.log .. ']]', addClass = 'plinkt-link no-border' }
end
if chopping_logs or buying_logs then
pole_info = pole_info or lookup_pole(weapon.pole.name)
row
:td(pole_info.level)
end
 
row
:td{ needed_poles .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed_poles } }
:td{ ('[[File:%s.png|link=%s|30px]]'):format(weapon.pole.name), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
:td{ '[[' .. weapon.pole.name .. ']]', addClass = 'plinkt-link no-border' }
else
if chopping_logs then
row
:na()
:td{ '<small>N/A</small>', addClass = 'table-na', attr = { ['data-sort-value'] = '0', colspan = '3' } }
end
if chopping_logs or buying_logs then
row
:na()
end
row
:td{ '<small>N/A</small>', addClass = 'table-na', attr = { ['data-sort-value'] = '0', colspan = '3' } }
end
 
row
:td{ needed .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed } }
:td{ ('[[File:%s.png|link=%s|30px]]'):format(weapon.name), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
:td{ '[[' .. weapon.name .. ']]', addClass = 'plinkt-link no-border' }
 
local cost = needed_ores * lookup_price(ingot.ore)
if chopping_logs then
-- No extra cost
elseif buying_logs then
if needed_logs then
cost = cost + needed_logs * lookup_price(pole_info.log)
end
else
if weapon.pole then
cost = cost + needed_poles * lookup_price(weapon.pole.name)
end
end
 
row:node(currency._cell(amount, { html = 'yes' }))
end
 
return result
persistant.in_table = nil
persistant.json = nil
persistant.version = nil
persistant.location_object = nil
end
 

Revision as of 14:28, 19 December 2024

Documentation for this module may be created at Module:Sandbox/User:Artoire/1/doc

--[[
mw.log(p._main{
	current_xp = 24,
	target_xp = 37,
	ingot = 'Maloic Adathril Ingot',
})
]]

require('strict')
require('Module:Mw.html extension')
local xp = require('Module:Experience')
local cache = require('Module:Break Isolation').get_module_store('Module:Sandbox/User:Artoire/1')
local currency = require('Module:Currency')
local lang = mw.language.getContentLanguage()

local function lookup_ingots()
	if cache.ingots then return cache.ingots end
	local ingots = {
		recipes = {},
		order = {}
	}
	cache.ingots = ingots
	for _, result in ipairs(mw.smw.ask{
		'[[Uses facility::Goblin Smelter||Gnome Smelter]]',
		['?Recipe JSON'] = '',
		mainlabel = '-',
		sort = 'Profession Level A',
		limit = '500'
	}) do
		result = mw.text.jsonDecode(result[1])
		local ingot = result.output[1].name
		ingots.recipes[ingot] = {
			xp = result.xp,
			facility = result.facility,
			ingot = result.output[1].name,
			ore = result.materials[1].name,
			level = result.level
		}
		table.insert(ingots.order, ingot)
	end
	return ingots
end

local function lookup_weapons()
	if cache.weapons then return cache.weapons end
	local ingots = lookup_ingots()
	local weapons = {}
	cache.weapons = weapons
	for _, result in ipairs(mw.smw.ask{
		'[[Uses facility::Goblin Forge||Gnome Forge]]',
		['?Recipe JSON'] = '',
		mainlabel = '-',
		sort = 'Profession Level A',
		limit = '500'
	}) do
		local lvl = result['Profession Level A']
		result = mw.text.jsonDecode(result[1])
		local ingot
		local pole
		for _, material in ipairs(result.materials) do
			if ingots.recipes[material.name] then
				assert(not ingot)
				ingot = material
			else
				assert(not pole)
				pole = material
			end
		end
		weapons[ingot.name] = weapons[ingot.name] or {}
		table.insert(weapons[ingot.name], {
			facility = result.facility,
			level = result.level,
			ingot = ingot,
			pole = pole,
			name = result.output[1].name,
			xp = result.xp
		})
	end
	return weapons
end

local function _lookup_price_uncached(item)
	local result = tonumber(mw.smw.ask{
		('[[Sold item::%s]]'):format(item),
		['?Shop buy price'] = '',
		mainlabel = '-'
	}[1][1])
	return result or -1
end

cache.lookup_price = cache.lookup_price or {}
local function lookup_price(item)
	cache.lookup_price[item] = cache.lookup_price[item] or _lookup_price_uncached(item)
	return cache.lookup_price[item]
end

local function _lookup_pole_uncached(pole)
	local pole_data = mw.text.jsonDecode(mw.smw.ask{
		('[[%s]]'):format(pole),
		['?Recipe JSON'] = '',
		mainlabel = '-'
	}[1][1])
	local post = pole_data.materials[1].name
	local post_data = mw.text.jsonDecode(mw.smw.ask{
		('[[%s]]'):format(post),
		['?Recipe JSON'] = '',
		mainlabel = '-'
	}[1][1])
	return {
		level = pole_data.level,
		pole = pole,
		post = post,
		log = post_data.materials[1].name
	}
end

cache.lookup_pole = cache.lookup_pole or {}
local function lookup_pole(pole)
	cache.lookup_pole[pole] = cache.lookup_pole[pole] or _lookup_pole_uncached(pole)
	return cache.lookup_pole[pole]
end

local function _lookup_ore_uncached(ore)
	local data = mw.smw.ask{
		('[[%s]]'):format(ore),
		['?Profession Level A'] = '',
		mainlabel = '-'
	}[1]
	return {
		level = tonumber(data[1])
	}
end

cache.lookup_ore = cache.lookup_ore or {}
local function lookup_ore(ore)
	cache.lookup_ore[ore] = cache.lookup_ore[ore] or _lookup_ore_uncached(ore)
	return cache.lookup_ore[ore]
end

local function _lookup_log_uncached(log)
	local data = mw.smw.ask{
		('[[%s]]'):format(ore),
		['?Profession Level A'] = '',
		mainlabel = '-'
	}[1]
	return {
		level = tonumber(data[1])
	}
end

cache.lookup_log = cache.lookup_log or {}
local function lookup_log(log)
	cache.lookup_log[log] = cache.lookup_log[log] or _lookup_log_uncached(log)
	return cache.lookup_log[log]
end

local p = {}

local p = {}

function p.ingots()
	return table.concat(lookup_ingots().order, ',')
end

function p.main(frame)
	return p._main(frame:getParent().args)
end

p.w = lookup_weapons

function p._main(args)
	local current_xp = tonumber(args.current_xp) or 0
	local current_lvl
	if current_xp <= 500 then
		current_lvl = current_xp
		current_xp = xp._total_xp(current_lvl)
	else
		current_lvl = xp._level_at(current_xp)
	end

	local target_xp = tonumber(args.target_xp) or 0	
	local target_lvl
	if target_xp <= 500 then
		target_lvl = target_xp
		target_xp = xp._total_xp(target_lvl)
	else
		target_lvl = xp._level_at(target_xp)
	end

	local remaining_xp = target_xp - current_xp

	local buying_poles = args.pole_buy
	local chopping_logs = buying_poles == 'none'
	local buying_logs = buying_poles == 'logs'
	buying_poles = not (buying_logs or chopping_logs)

	local ingot = lookup_ingots().recipes[args.ingot]

	local result = mw.html.create()

	result:wikitext(('To get from %s xp (level %s) to %s xp (level %s) requires %s experience'):format(current_xp, current_lvl, target_xp, target_lvl, remaining_xp))

	local tbl = result:tag('table')
		:addClass('wikitable sortable')

	local function skillclickpic(profession)
		return ('[[File:%s small icon.png|15px|link=%s|%s level]]'):format(profession, profession, profession)
	end
	
	local colspan = 24
	if chopping_logs then
		colspan = colspan + 4
	end
	if chopping_logs or buying_logs then
		colspan = colspan + 1
	end

	tbl
		:tr()
			:th(skillclickpic('Miner')):done()
			:th{ 'Ore', attr = { colspan = '3' } }:done()
			:th(skillclickpic('Blacksmith')):done()
			:th{ 'Ingot', attr = { colspan = '3' } }:done()
			:IF(chopping_logs)
				:th(skillclickpic('Woodcutter'))
				:th{ 'Log', attr = { colspan = '3' } }:done()
			:th()
			:IF(chopping_logs or buying_logs)
				:th(skillclickpic('Carpenter'))
			:DONE()
			:th{ 'Pole', attr = { colspan = '3' } }:done()
			:th{ 'Product', attr = { colspan = '3' } }:done()
			:th{ 'Cost', attr = { colspan = '10' } }:done()
		:done()

	for _, weapon in lookup_weapons()[ingot.name] do
		if not ingot.xp then
			tbl
				:tr()
					:td{
						'Missing XP for smelting [[' .. ingot.name .. ']]; Please [' .. mw.uri.fullUrl(ingot.name, 'action=edit&section=1') .. ' edit the page] to add the experience earned (after |exp =)',
						attr = { colspan = colspan }
					}
				:done()
			break
		end
		if not weapon.xp then
			tbl
				:tr()
					:td{
						'Missing XP for creating [[' .. weapon.name .. ']]; Please ['.. mw.uri.fullUrl(weapon.name, 'action=edit&section=1') .. ' edit the page] to add the experience earned (after |exp =)',
						attr = { colspan = colspan }
					}
				:done()
			break
		end
		local xp_per = weapon.xp + ingot.xp * weapon.ingot.quantity
		local needed = math.ceil(remaining_xp / xp_per)

		local needed_ores = needed * weapon.ingot.quantity
		local row = tbl
			:tr()
				:td(lookup_ore(ingot.ore).level)
				:td{ needed_ores .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right', ['data-sort-value'] = needed_ores } }
				:td{ ('[[File:%s.png|link=%s|30px]]'):format(ingot.ore), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
				:td{ '[[' .. ingot.ore .. ']]', addClass = 'plinkt-link no-border' }

		local pole_info
		local needed_logs, needed_poles

		if weapon.pole then
			needed_poles = needed * weapon.pole.quantity
			if chopping_logs then
				pole_info = lookup_pole(weapon.pole.name)
				needed_logs = math.ceil(needed_poles / 2)
				row
					:td(lookup_log(pole_info.log).level)
					:td{ needed_logs .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed_logs } }
					:td{ ('[[File:%s.png|link=%s|30px]]'):format(pole_info.log), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
					:td{ '[[' .. pole_info.log .. ']]', addClass = 'plinkt-link no-border' }
			end
			if chopping_logs or buying_logs then
				pole_info = pole_info or lookup_pole(weapon.pole.name)
				row
					:td(pole_info.level)
			end

			row
				:td{ needed_poles .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed_poles } }
				:td{ ('[[File:%s.png|link=%s|30px]]'):format(weapon.pole.name), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
				:td{ '[[' .. weapon.pole.name .. ']]', addClass = 'plinkt-link no-border' }
		else
			if chopping_logs then
				row
					:na()
					:td{ '<small>N/A</small>', addClass = 'table-na', attr = { ['data-sort-value'] = '0', colspan = '3' } }
			end
			if chopping_logs or buying_logs then
				row
					:na()
			end
			row
				:td{ '<small>N/A</small>', addClass = 'table-na', attr = { ['data-sort-value'] = '0', colspan = '3' } }
		end

		row
			:td{ needed .. '&times;', css = { ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }, attr = { ['data-sort-value'] = needed } }
			:td{ ('[[File:%s.png|link=%s|30px]]'):format(weapon.name), css = { ['border-left'] = '0', ['padding-left'] = '0' }, addClass = 'plinkt-image no-border' }
			:td{ '[[' .. weapon.name .. ']]', addClass = 'plinkt-link no-border' }

		local cost = needed_ores * lookup_price(ingot.ore)
		if chopping_logs then
			-- No extra cost
		elseif buying_logs then
			if needed_logs then
				cost = cost + needed_logs * lookup_price(pole_info.log)
			end
		else
			if weapon.pole then
				cost = cost + needed_poles * lookup_price(weapon.pole.name)
			end
		end

		row:node(currency._cell(amount, { html = 'yes' }))
	end

	return result
end

return p