<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASpell_cost_table</id>
	<title>Module:Spell cost table - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASpell_cost_table"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Spell_cost_table&amp;action=history"/>
	<updated>2026-04-30T17:39:15Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=Module:Spell_cost_table&amp;diff=38436&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;-- &lt;pre&gt;  local p = {}  local gep = require(&#039;Module:Exchange&#039;)._price local coins = require(&#039;Module:Coins&#039;)._amount  local combo_runes = { 	[&#039;mist rune&#039;] = { [&#039;air rune&#039;] = true, [&#039;water rune&#039;] = true }, 	[&#039;dust rune&#039;] = { [&#039;air rune&#039;] = true, [&#039;earth rune&#039;] = true }, 	[&#039;mud rune&#039;] = { [&#039;water rune&#039;] = true, [&#039;earth rune&#039;] = true }, 	[&#039;smoke rune&#039;] = { [&#039;air rune&#039;] = true, [&#039;fire rune&#039;] = true }, 	[&#039;steam rune&#039;] = { [&#039;water rune&#039;] = true, [&#039;fire rune&#039;] = true }, 	[&#039;lava...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Spell_cost_table&amp;diff=38436&amp;oldid=prev"/>
		<updated>2024-10-17T10:23:55Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- &amp;lt;pre&amp;gt;  local p = {}  local gep = require(&amp;#039;Module:Exchange&amp;#039;)._price local coins = require(&amp;#039;Module:Coins&amp;#039;)._amount  local combo_runes = { 	[&amp;#039;mist rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;water rune&amp;#039;] = true }, 	[&amp;#039;dust rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true }, 	[&amp;#039;mud rune&amp;#039;] = { [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true }, 	[&amp;#039;smoke rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true }, 	[&amp;#039;steam rune&amp;#039;] = { [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true }, 	[&amp;#039;lava...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local gep = require(&amp;#039;Module:Exchange&amp;#039;)._price&lt;br /&gt;
local coins = require(&amp;#039;Module:Coins&amp;#039;)._amount&lt;br /&gt;
&lt;br /&gt;
local combo_runes = {&lt;br /&gt;
	[&amp;#039;mist rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;water rune&amp;#039;] = true },&lt;br /&gt;
	[&amp;#039;dust rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true },&lt;br /&gt;
	[&amp;#039;mud rune&amp;#039;] = { [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true },&lt;br /&gt;
	[&amp;#039;smoke rune&amp;#039;] = { [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true },&lt;br /&gt;
	[&amp;#039;steam rune&amp;#039;] = { [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true },&lt;br /&gt;
	[&amp;#039;lava rune&amp;#039;] = { [&amp;#039;earth rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local non_rune_items = {&lt;br /&gt;
	[&amp;#039;banana&amp;#039;] = 1,&lt;br /&gt;
	[&amp;#039;unpowered orb&amp;#039;] = true,&lt;br /&gt;
	[&amp;#039;soft clay&amp;#039;] = true,&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
local staves = {&lt;br /&gt;
	--[[Weapon Structure&lt;br /&gt;
		Weapons are structured to allow specification of when and how they are included in the table. The structure for each entry is detailed below.&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;&amp;lt;Parameters&amp;gt;&amp;gt;&lt;br /&gt;
		name		 : The name of the item&lt;br /&gt;
		[&amp;#039;_____&amp;#039;]	 : The name of a fully provided rune (or item), should be set to true&lt;br /&gt;
		conditions   : (Optional) An array of conditions for item (or Modifier) inclusion, detailed below&lt;br /&gt;
		alternatives : (Optional) A list of alternative items, these will be listed in an explain subscript if they haven&amp;#039;t been included in the table&lt;br /&gt;
		extras		 : (Optional Modifier) An array of additional items to the row, each item accepts conditions in addition to the parameters below&lt;br /&gt;
			item	 : The name of the item&lt;br /&gt;
			quantity : The amount of the item&lt;br /&gt;
		negations	 : (Optional Modifier) An array of negations (i.e.) a chance to save a rune, conditions should be used to specify things such as rune type or required arguments&lt;br /&gt;
			magnitude: The multiplier to negate by. Should be 1 - (% to save), e.g Kodai wand has 15% so magnitude is 1 - 0.15 = 0.85&lt;br /&gt;
			offset: an offset to subtract. Final rune cost is (base cost - offset)*magnitude.&lt;br /&gt;
		&amp;lt;&amp;lt;Conditions&amp;gt;&amp;gt;&lt;br /&gt;
		args		 : An array of {argument, (optional) value} checks for arg, if a value is included it requires that specific value&lt;br /&gt;
		runes		 : Array of rune types, should NOT be used at root level, i.e. should only be used as a condition for modifiers&lt;br /&gt;
		rune_count	 : A minimum number of matching runes to be included, should ONLY be used at root level, i.e. shouldn&amp;#039;t be used as a condition for modifiers&lt;br /&gt;
	--]]&lt;br /&gt;
	{ name = &amp;#039;staff of air&amp;#039;, [&amp;#039;air rune&amp;#039;] = true, alternatives = {&amp;#039;mist battlestaff&amp;#039;, &amp;#039;smoke battlestaff&amp;#039;, &amp;#039;dust battlestaff&amp;#039;} },&lt;br /&gt;
	{ name = &amp;#039;staff of water&amp;#039;, [&amp;#039;water rune&amp;#039;] = true, alternatives = {&amp;#039;mist battlestaff&amp;#039;, &amp;#039;mud battlestaff&amp;#039;, &amp;#039;steam battlestaff&amp;#039;, &amp;#039;kodai wand&amp;#039;} },&lt;br /&gt;
	{ name = &amp;#039;staff of earth&amp;#039;, [&amp;#039;earth rune&amp;#039;] = true, alternatives = {&amp;#039;dust battlestaff&amp;#039;, &amp;#039;mud battlestaff&amp;#039;, &amp;#039;lava battlestaff&amp;#039;} },&lt;br /&gt;
	{ name = &amp;#039;staff of fire&amp;#039;, [&amp;#039;fire rune&amp;#039;] = true, alternatives = {&amp;#039;steam battlestaff&amp;#039;, &amp;#039;lava battlestaff&amp;#039;, &amp;#039;smoke battlestaff&amp;#039;} },&lt;br /&gt;
	&lt;br /&gt;
	--We don&amp;#039;t want to including combination staves unless they&amp;#039;re actually granting a benefit&lt;br /&gt;
	{ name = &amp;#039;mud battlestaff&amp;#039;, [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true, conditions = { rune_count = 2 }},&lt;br /&gt;
	{ name = &amp;#039;steam battlestaff&amp;#039;, [&amp;#039;water rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true, conditions = { rune_count = 2 } },&lt;br /&gt;
	{ name = &amp;#039;lava battlestaff&amp;#039;, [&amp;#039;earth rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true, conditions = { rune_count = 2 } },&lt;br /&gt;
	{ name = &amp;#039;smoke battlestaff&amp;#039;, [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;fire rune&amp;#039;] = true, conditions = { rune_count = 2 } },&lt;br /&gt;
	{ name = &amp;#039;dust battlestaff&amp;#039;, [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;earth rune&amp;#039;] = true, conditions = { rune_count = 2 } },&lt;br /&gt;
	{ name = &amp;#039;mist battlestaff&amp;#039;, [&amp;#039;air rune&amp;#039;] = true, [&amp;#039;water rune&amp;#039;] = true, conditions = { rune_count = 2 } },&lt;br /&gt;
	&lt;br /&gt;
	--Staff of the dead and Kodai only need to be shown for offensive spells, thus we can condition their inclusion based on the is_offensive arg&lt;br /&gt;
	{ name = &amp;#039;staff of the dead&amp;#039;, conditions = {args = {{&amp;#039;is_offensive&amp;#039;}}}, alternatives = {&amp;#039;staff of light, staff of balance, or toxic variant&amp;#039;}, negations = {{magnitude = 0.857}} },&lt;br /&gt;
	{ name = &amp;#039;kodai wand&amp;#039;, [&amp;#039;water rune&amp;#039;] = true, conditions = {args = {{&amp;#039;is_offensive&amp;#039;}}}, negations = {{magnitude = 0.85}} },&lt;br /&gt;
	&lt;br /&gt;
	--Partial negation should be conditioned upon the rune(s), placed INSIDE the negation parameter&lt;br /&gt;
	{ name = &amp;quot;bryophyta&amp;#039;s staff&amp;quot;, negations = {{conditions = {runes = {&amp;#039;nature rune&amp;#039;}}, offset = (1/15)}} }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local offhands = {&lt;br /&gt;
	--Tome of Fire only sometimes uses pages, so we want to condition the extras to the uses_pages arg that&lt;br /&gt;
	{ name = &amp;#039;tome of fire&amp;#039;, [&amp;#039;fire rune&amp;#039;] = true, extras = {{conditions = {args = {{&amp;#039;uses_pages&amp;#039;}}}, item = &amp;#039;Burnt page&amp;#039;, quantity = 1/20 }} },&lt;br /&gt;
	{ name = &amp;#039;tome of water&amp;#039;, [&amp;#039;water rune&amp;#039;] = true, extras = {{conditions = {args = {{&amp;#039;uses_pages&amp;#039;}}}, item = &amp;#039;Soaked page&amp;#039;, quantity = 1/20}} },&lt;br /&gt;
	--(Following to be added on Sept 25th 2024)&lt;br /&gt;
	{ name = &amp;#039;tome of earth&amp;#039;, [&amp;#039;earth rune&amp;#039;] = true, extras = {{conditions = {args = {{&amp;#039;uses_pages&amp;#039;}}}, item = &amp;#039;Soiled page&amp;#039;, quantity = 1/20}} },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	&lt;br /&gt;
	--Parse the numbered rune arguments into an array&lt;br /&gt;
	local runes = {}&lt;br /&gt;
	for i=1,10 do&lt;br /&gt;
		if not args[&amp;#039;Rune&amp;#039;..i] then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local rune = string.lower(args[&amp;#039;Rune&amp;#039;..i])&lt;br /&gt;
		&lt;br /&gt;
		-- Unless it&amp;#039;s found in non-rune items, we assume that it&amp;#039;s a rune and append &amp;quot; rune&amp;quot; to the end&lt;br /&gt;
		if not non_rune_items[rune] then&lt;br /&gt;
		    rune = rune..&amp;#039; rune&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		    &lt;br /&gt;
		local num = tonumber(args[&amp;#039;Rune&amp;#039;..i..&amp;#039;num&amp;#039;] or 1)&lt;br /&gt;
		table.insert(runes,{rune,num,{}})&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return p.create_table(runes, args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- We want backwards compatibility for the old module, until things are moved over&lt;br /&gt;
function p._main(runes, no_staff, uses_pages)&lt;br /&gt;
	return p.create_table({[&amp;#039;no_staff&amp;#039;] = no_staff, [&amp;#039;uses_pages&amp;#039;] = uses_pages})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.create_table(runes, args)&lt;br /&gt;
	-- Create the headers and insert the first row for basic runes&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
					:addClass(&amp;#039;wikitable&amp;#039;)&lt;br /&gt;
					:tag(&amp;#039;caption&amp;#039;)&lt;br /&gt;
						:wikitext(&amp;#039;Spell cost&amp;#039;)&lt;br /&gt;
					:done()&lt;br /&gt;
					:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
						:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
							:wikitext(&amp;#039;Input&amp;#039;)&lt;br /&gt;
						:done()&lt;br /&gt;
						:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
							:wikitext(&amp;#039;Cost&amp;#039;)&lt;br /&gt;
						:done()&lt;br /&gt;
					:done()&lt;br /&gt;
					:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
						:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
							:wikitext(make_pics(runes))&lt;br /&gt;
						:done()&lt;br /&gt;
						:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
							:wikitext(total_price(runes))&lt;br /&gt;
						:done()&lt;br /&gt;
					:done()&lt;br /&gt;
&lt;br /&gt;
	-- Decide what combo runes can be used in the spell&lt;br /&gt;
	local combos_used = {}&lt;br /&gt;
	for i, v in pairs(combo_runes) do&lt;br /&gt;
		local amtused = 0&lt;br /&gt;
		local runes_temp = {}&lt;br /&gt;
		for j, x in ipairs(runes) do&lt;br /&gt;
			if v[x[1]] then&lt;br /&gt;
				if x[2] &amp;gt; amtused then&lt;br /&gt;
				   amtused = x[2]&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(runes_temp, x)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if amtused &amp;gt; 0 then&lt;br /&gt;
			table.insert(runes_temp,{i, amtused,{}})&lt;br /&gt;
			table.insert(combos_used,runes_temp)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if #combos_used &amp;gt; 0 then&lt;br /&gt;
		ret:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;,&amp;#039;2&amp;#039;)&lt;br /&gt;
				:wikitext(&amp;#039;Combo runes&amp;#039;)&lt;br /&gt;
			:done()&lt;br /&gt;
		:done()&lt;br /&gt;
		for _, v in ipairs(combos_used) do&lt;br /&gt;
			ret:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:wikitext(make_pics(v))&lt;br /&gt;
				:done()&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:wikitext(total_price(v))&lt;br /&gt;
				:done()&lt;br /&gt;
			:done()&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- add relevant main-hands to the weapons table&lt;br /&gt;
	local weapons = {}&lt;br /&gt;
	local relevant_staves = {}&lt;br /&gt;
	if (not args.nostaff and not args.no_staff) or (args.nostaff == 0 or args.no_staff == 0) then&lt;br /&gt;
		relevant_staves = composeWeapons(staves, runes, args)&lt;br /&gt;
		weapons = join (weapons, relevant_staves)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- add relevant off-hands to the weapons table&lt;br /&gt;
	local relevant_offhands = {}&lt;br /&gt;
	if (not args.nooffhand and not args.no_offhand) and ((not args.nostaff and not args.no_staff) or (args.nostaff ~= 1 or args.no_staff ~= 1))  then&lt;br /&gt;
		relevant_offhands = composeWeapons(offhands, runes, args)&lt;br /&gt;
		weapons = join(weapons, relevant_offhands)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local relevant_combos = {}&lt;br /&gt;
	-- add relevant main-+off-hand combinations to the weapons table&lt;br /&gt;
	relevant_combos = compose_combinations(relevant_staves, relevant_offhands, runes, args)&lt;br /&gt;
	&lt;br /&gt;
	local offhand_header = &amp;#039;Off-hands&amp;#039;&lt;br /&gt;
	if #relevant_combos &amp;gt; 0 then&lt;br /&gt;
		offhand_header = &amp;#039;Main and off-hands&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if #relevant_staves &amp;gt; 0 then&lt;br /&gt;
		ret:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;,&amp;#039;2&amp;#039;)&lt;br /&gt;
				:wikitext(&amp;#039;Main-hands&amp;#039;)&lt;br /&gt;
			:done()&lt;br /&gt;
		:done()&lt;br /&gt;
		ret = weapon_output(relevant_staves,runes,weapons,ret,args)&lt;br /&gt;
	end&lt;br /&gt;
	if #relevant_offhands &amp;gt; 0 then&lt;br /&gt;
		ret:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;,&amp;#039;2&amp;#039;)&lt;br /&gt;
				:wikitext(offhand_header)&lt;br /&gt;
			:done()&lt;br /&gt;
		:done()&lt;br /&gt;
		ret = weapon_output(relevant_offhands,runes,weapons,ret,args)&lt;br /&gt;
		ret = weapon_output(relevant_combos,runes,weapons,ret,args)&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Here we implement how conditions are checked.&lt;br /&gt;
function check_conditions(conditions, args, rune, rune_count)&lt;br /&gt;
	local ret = true --create a return variable&lt;br /&gt;
	&lt;br /&gt;
	if conditions.args then -- Scan through all args to make sure they match&lt;br /&gt;
		for _, condition in ipairs(conditions.args) do&lt;br /&gt;
			ret = ret and args[condition[1]] and ((not condition[2]) or (condition[2] == args[condition[1]]))&lt;br /&gt;
			-- If an arg has no listed value, it&amp;#039;s assumed that anything but a nil value is valid, otherwise check&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if conditions.rune_count then ret = ret and rune_count &amp;gt;= conditions.rune_count end &lt;br /&gt;
	&lt;br /&gt;
	if conditions.runes then -- Scan through all runes for which this condition applies, if a match is found, condition passes&lt;br /&gt;
		local rune_present = false&lt;br /&gt;
		for _, irune in ipairs(conditions.runes) do&lt;br /&gt;
			rune_present = rune_present or rune == irune&lt;br /&gt;
		end&lt;br /&gt;
		ret = ret and rune_present&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function composeWeapons(list, runes, args)&lt;br /&gt;
	local a = {}&lt;br /&gt;
	for i, v in ipairs(list) do&lt;br /&gt;
		--Iterate through runes to search for a match on the staff&amp;#039;s provided runes&lt;br /&gt;
		&lt;br /&gt;
		local total = 0&lt;br /&gt;
		local rune_count = 0&lt;br /&gt;
		local has_negation = false&lt;br /&gt;
		for j,k in ipairs(runes) do&lt;br /&gt;
			total = total + 1&lt;br /&gt;
			if v[k[1]] then&lt;br /&gt;
				rune_count = rune_count + 1&lt;br /&gt;
			else&lt;br /&gt;
				for ineg, negation in ipairs(v.negations or {}) do&lt;br /&gt;
					-- If the weapon has a negation and either fulfills its conditions OR has no conditions listed, apply it&lt;br /&gt;
					has_negation = has_negation or (not negation.conditions or check_conditions(negation.conditions, args, k[1])) &lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- No need to continue if negation is found&lt;br /&gt;
				if has_negation then break end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if (not v.conditions or check_conditions(v.conditions, args, nil, rune_count)) and (has_negation or rune_count &amp;gt; 0) then&lt;br /&gt;
			table.insert(a, {v})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return a&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function compose_combinations(listA, listB, runes, args)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	&lt;br /&gt;
	for i_a, a in ipairs(listA) do&lt;br /&gt;
		for i_b, b in ipairs(listB) do&lt;br /&gt;
			-- eliminate redundancy e.g. fire staff + tome of fire is redundant&lt;br /&gt;
			for _, rune_data in ipairs(runes) do&lt;br /&gt;
				local rune_name = rune_data[1]&lt;br /&gt;
				if (not a[1][rune_name] and b[1][rune_name]) then&lt;br /&gt;
					table.insert(ret, {a[1], b[1]})&lt;br /&gt;
				else&lt;br /&gt;
					-- We want to check if the combined negations actually apply, so we calculate both negations then see if the combined is less than the staff&amp;#039;s&lt;br /&gt;
					local negationMagA = 1&lt;br /&gt;
					for ineg, negation in ipairs(a[1].negations or {}) do&lt;br /&gt;
						-- If the weapon has a negation and either fulfills its conditions OR has no conditions listed, apply it&lt;br /&gt;
						if (not negation.conditions or check_conditions(negation.conditions, args, rune_data[1])) then&lt;br /&gt;
							negationMagA = negationMagA * (negation.magnitude or 1)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					local negationMagB = 1&lt;br /&gt;
					for ineg, negation in ipairs(b[1].negations or {}) do&lt;br /&gt;
						-- If the weapon has a negation and either fulfills its conditions OR has no conditions listed, apply it&lt;br /&gt;
						if (not negation.conditions or check_conditions(negation.conditions, args, rune_data[1])) then&lt;br /&gt;
							negationMagB = negationMagB * (negation.magnitude or 1)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					&lt;br /&gt;
					if negationMagA*negationMagB &amp;lt; negationMagA then table.insert(ret, {a[1], b[1]}) end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function weapon_output(weapons, runes, all, ret, args)&lt;br /&gt;
	--For each weapon, scan through the runes and choose what to display&lt;br /&gt;
	for _, weapon_data in ipairs(weapons) do&lt;br /&gt;
		local tbl = {}&lt;br /&gt;
		for rune_i, rune_data in ipairs(runes) do&lt;br /&gt;
			if weapon_data[1][rune_data[1]] or (weapon_data[2] and weapon_data[2][rune_data[1]]) then&lt;br /&gt;
				-- do nothing&lt;br /&gt;
			else&lt;br /&gt;
				local negationMag = 1&lt;br /&gt;
				local negationOffset = 0&lt;br /&gt;
				local negations = weapon_data[1].negations or {}&lt;br /&gt;
				if weapon_data[2] then negations = join(negations, weapon_data[2].negations or {}) end&lt;br /&gt;
				&lt;br /&gt;
				for ineg, negation in ipairs(negations) do&lt;br /&gt;
					-- If the weapon has a negation and either fulfills its conditions OR has no conditions listed, apply it&lt;br /&gt;
					if (not negation.conditions or check_conditions(negation.conditions, args, rune_data[1])) then&lt;br /&gt;
						negationMag = negationMag * (negation.magnitude or 1)&lt;br /&gt;
						negationOffset = negationOffset + (negation.offset or 0)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				if negationMag == 0 then&lt;br /&gt;
					-- Do nothing&lt;br /&gt;
				elseif negationMag &amp;lt; 1 or negationOffset &amp;gt; 0 then&lt;br /&gt;
					table.insert(tbl, { rune_data[1], round( negationMag * (rune_data[2] - negationOffset), 2), {} })&lt;br /&gt;
				else&lt;br /&gt;
					table.insert(tbl, { rune_data[1], rune_data[2], {}} )&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local extras = weapon_data[1].extras or {}&lt;br /&gt;
		if weapon_data[2] then extras = join(extras, weapon_data[2].extras or {}) end&lt;br /&gt;
		for i,v in ipairs(extras) do&lt;br /&gt;
			if not v.conditions or check_conditions(v.conditions, args, {}) then&lt;br /&gt;
				table.insert(tbl, {v.item, v.quantity, {}})&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		for i,weapon in ipairs(weapon_data) do&lt;br /&gt;
			table.insert(tbl,{weapon.name, 0, weapon})&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		ret:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:wikitext(make_pics(tbl, all))&lt;br /&gt;
				:done()&lt;br /&gt;
				:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:wikitext(total_price(tbl))&lt;br /&gt;
				:done()&lt;br /&gt;
			:done()&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function join(tbl1, tbl2)&lt;br /&gt;
	local ret = tbl1&lt;br /&gt;
	&lt;br /&gt;
	for _, item in ipairs(tbl2 or {}) do&lt;br /&gt;
		table.insert(ret, item)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function round(n, digits)&lt;br /&gt;
	local working = math.pow(10, digits)&lt;br /&gt;
	local workingMod = math.fmod(n * working, 10)&lt;br /&gt;
	&lt;br /&gt;
	if workingMod &amp;gt;= 5 then&lt;br /&gt;
		return math.ceil(n * working)/working&lt;br /&gt;
	else&lt;br /&gt;
		return math.floor(n * working)/working&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function make_pics(arg, others)&lt;br /&gt;
	local runes = {}&lt;br /&gt;
	for _, v in ipairs(arg) do&lt;br /&gt;
		if type(v[1]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			local _v = v[1]&lt;br /&gt;
			for _, w in ipairs(_v) do&lt;br /&gt;
				table.insert(runes, {w, v[2]})&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(runes, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = {}&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(runes) do&lt;br /&gt;
		if v[2] &amp;gt; 0 then&lt;br /&gt;
			table.insert(ret,&amp;#039;&amp;lt;sup&amp;gt;&amp;#039;..v[2]..&amp;#039;&amp;lt;/sup&amp;gt;&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(ret,&amp;#039;[[File:&amp;#039;..v[1]..&amp;#039;.png|link=&amp;#039;..v[1]..&amp;#039;]] &amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		local alts = &amp;quot;&amp;quot;&lt;br /&gt;
		local altNext = &amp;quot;&amp;quot;&lt;br /&gt;
		for _, alt in ipairs(v[3].alternatives or {}) do&lt;br /&gt;
			&lt;br /&gt;
			local weapon_present = false&lt;br /&gt;
			for i, weapon in ipairs(others) do&lt;br /&gt;
				if alt == weapon[1].name then&lt;br /&gt;
					weapon_present = true&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			if not weapon_present then &lt;br /&gt;
				if #alts == 0 then&lt;br /&gt;
					alts = altNext&lt;br /&gt;
				else&lt;br /&gt;
				    alts = alts..&amp;quot;, &amp;quot;..altNext&lt;br /&gt;
				end&lt;br /&gt;
				altNext = alt&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if #altNext ~= 0 then&lt;br /&gt;
			if #alts == 0 then alts = altNext&lt;br /&gt;
			else alts = alts..&amp;quot;, or &amp;quot;..altNext	end&lt;br /&gt;
			&lt;br /&gt;
			table.insert(ret,&amp;quot;&amp;lt;sub class=&amp;#039;explain&amp;#039; title=&amp;#039;Alternatively, a &amp;quot;..alts..&amp;quot; can be used.&amp;#039; style=&amp;#039;text-decoration:underline dotted&amp;#039;&amp;gt;Alt&amp;lt;/sub&amp;gt;&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function total_price(runes)&lt;br /&gt;
	local ret = 0&lt;br /&gt;
	for _, v in ipairs(runes) do&lt;br /&gt;
		if v[2] &amp;gt; 0 then&lt;br /&gt;
			ret = ret + gep(v[1]) * v[2]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return coins(round(ret,0))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>