<?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%3AHerb_Farming_calculator</id>
	<title>Module:Herb Farming calculator - 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%3AHerb_Farming_calculator"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Herb_Farming_calculator&amp;action=history"/>
	<updated>2026-05-01T08:57:19Z</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:Herb_Farming_calculator&amp;diff=34980&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;local p = {}  local coins = require(&#039;Module:Coins&#039;)._amount local gePrices = mw.loadJsonData(&#039;Module:GEPrices/data.json&#039;) local farmingData = mw.loadData(&#039;Module:Skill calc/Farming&#039;) local paramTest = require(&#039;Module:Paramtest&#039;) local yesNo = require(&#039;Module:Yesno&#039;) local scp = require(&#039;Module:SCP&#039;)._main local listToText = mw.text.listToText  local warningTag = &#039; &lt;span style=&quot;color:red;&quot;&gt;&lt;b&gt;*&lt;/b&gt;&lt;/span&gt;&#039; local warningNote = &#039;&lt;span style=&quot;color:red;&quot;&gt;&lt;b&gt;*&lt;/b&gt;&lt;/span&gt; It c...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Herb_Farming_calculator&amp;diff=34980&amp;oldid=prev"/>
		<updated>2024-10-16T23:12:15Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local p = {}  local coins = require(&amp;#039;Module:Coins&amp;#039;)._amount local gePrices = mw.loadJsonData(&amp;#039;Module:GEPrices/data.json&amp;#039;) local farmingData = mw.loadData(&amp;#039;Module:Skill calc/Farming&amp;#039;) local paramTest = require(&amp;#039;Module:Paramtest&amp;#039;) local yesNo = require(&amp;#039;Module:Yesno&amp;#039;) local scp = require(&amp;#039;Module:SCP&amp;#039;)._main local listToText = mw.text.listToText  local warningTag = &amp;#039; &amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;#039; local warningNote = &amp;#039;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt; It c...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local coins = require(&amp;#039;Module:Coins&amp;#039;)._amount&lt;br /&gt;
local gePrices = mw.loadJsonData(&amp;#039;Module:GEPrices/data.json&amp;#039;)&lt;br /&gt;
local farmingData = mw.loadData(&amp;#039;Module:Skill calc/Farming&amp;#039;)&lt;br /&gt;
local paramTest = require(&amp;#039;Module:Paramtest&amp;#039;)&lt;br /&gt;
local yesNo = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local scp = require(&amp;#039;Module:SCP&amp;#039;)._main&lt;br /&gt;
local listToText = mw.text.listToText&lt;br /&gt;
&lt;br /&gt;
local warningTag = &amp;#039; &amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
local warningNote = &amp;#039;&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;*&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt; It costs more to use [[Resurrect Crops]] instead of replanting with a new seed. This is based on the cost of the seed with your chance to resurrect it.\n&amp;#039;&lt;br /&gt;
&lt;br /&gt;
local herbs = {&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Guam leaf&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 25, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Marrentill&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 28, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Tarromin&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 31, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Harralander&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 36, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Goutweed&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 39, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Ranarr weed&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 39, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Toadflax&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 43, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Irit leaf&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 46, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Avantoe&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 50, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Kwuarm&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 54, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Snapdragon&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 57, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Huasca&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 58, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Cadantine&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 60, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Lantadyme&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 64, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Dwarf weed&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 67, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
	{ [&amp;#039;name&amp;#039;] = &amp;#039;Torstol&amp;#039;, [&amp;#039;lowCTS&amp;#039;] = 71, [&amp;#039;highCTS&amp;#039;] = 80 },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local UnfinishedPotions = {&lt;br /&gt;
	[&amp;#039;Guam leaf&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 3, [&amp;#039;potion&amp;#039;] = &amp;#039;Guam potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Marrentill&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 5, [&amp;#039;potion&amp;#039;] = &amp;#039;Marrentill potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Tarromin&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 12, [&amp;#039;potion&amp;#039;] = &amp;#039;Tarromin potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Harralander&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 22, [&amp;#039;potion&amp;#039;] = &amp;#039;Harralander potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Goutweed&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 0, [&amp;#039;potion&amp;#039;] = &amp;#039;Vial of water&amp;#039; },&lt;br /&gt;
	[&amp;#039;Ranarr weed&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 30, [&amp;#039;potion&amp;#039;] = &amp;#039;Ranarr potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Toadflax&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 34, [&amp;#039;potion&amp;#039;] = &amp;#039;Toadflax potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Irit leaf&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 45, [&amp;#039;potion&amp;#039;] = &amp;#039;Irit potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Avantoe&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 50, [&amp;#039;potion&amp;#039;] = &amp;#039;Avantoe potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Kwuarm&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 55, [&amp;#039;potion&amp;#039;] = &amp;#039;Kwuarm potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Huasca&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 58, [&amp;#039;potion&amp;#039;] = &amp;#039;Huasca potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Snapdragon&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 63, [&amp;#039;potion&amp;#039;] = &amp;#039;Snapdragon potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Cadantine&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 66, [&amp;#039;potion&amp;#039;] = &amp;#039;Cadantine potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Lantadyme&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 69, [&amp;#039;potion&amp;#039;] = &amp;#039;Lantadyme potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Dwarf weed&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 72, [&amp;#039;potion&amp;#039;] = &amp;#039;Dwarf weed potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Torstol&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 78, [&amp;#039;potion&amp;#039;] = &amp;#039;Torstol potion (unf)&amp;#039; },&lt;br /&gt;
	[&amp;#039;Cadantineblood&amp;#039;] = { [&amp;#039;herblore&amp;#039;] = 80, [&amp;#039;potion&amp;#039;] = &amp;#039;Cadantine blood potion (unf)&amp;#039; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local compostChanceToLoseLifeReduction = {&lt;br /&gt;
	[&amp;#039;None&amp;#039;] = 1,&lt;br /&gt;
	[&amp;#039;Compost&amp;#039;] = 2,&lt;br /&gt;
	[&amp;#039;Supercompost&amp;#039;] = 5,&lt;br /&gt;
	[&amp;#039;Ultracompost&amp;#039;] = 10,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local compostLifeValue = {&lt;br /&gt;
	[&amp;#039;None&amp;#039;] = 0,&lt;br /&gt;
	[&amp;#039;Compost&amp;#039;] = 1,&lt;br /&gt;
	[&amp;#039;Supercompost&amp;#039;] = 2,&lt;br /&gt;
	[&amp;#039;Ultracompost&amp;#039;] = 3,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Yield increases are actually a flat increase in chance to save calculation&lt;br /&gt;
-- 5% is +10, 10% is +17, 15% is +25&lt;br /&gt;
local percentToValueIncreaseCTS = {&lt;br /&gt;
	[&amp;#039;0&amp;#039;] = 0,&lt;br /&gt;
	[&amp;#039;0.05&amp;#039;] = 10,&lt;br /&gt;
	[&amp;#039;0.1&amp;#039;] = 17,&lt;br /&gt;
	[&amp;#039;0.15&amp;#039;] = 25,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local goutweedSanfewExchange = gePrices[&amp;#039;Grimy guam leaf&amp;#039;] * 32/128 + gePrices[&amp;#039;Grimy marrentill&amp;#039;] * 24/128 + gePrices[&amp;#039;Grimy tarromin&amp;#039;] * 18/128 + gePrices[&amp;#039;Grimy harralander&amp;#039;] * 14/128 + gePrices[&amp;#039;Grimy ranarr weed&amp;#039;] * 11/128 + gePrices[&amp;#039;Grimy irit leaf&amp;#039;] * 8/128 + gePrices[&amp;#039;Grimy avantoe&amp;#039;] * 6/128 + gePrices[&amp;#039;Grimy kwuarm&amp;#039;] * 5/128  + gePrices[&amp;#039;Grimy cadantine&amp;#039;] * 4/128 + gePrices[&amp;#039;Grimy lantadyme&amp;#039;] * 3/128 + gePrices[&amp;#039;Grimy dwarf weed&amp;#039;] * 3/128&lt;br /&gt;
&lt;br /&gt;
function createHeader(farmingLevel, sell, tableCaption)&lt;br /&gt;
	local header = mw.html.create(&amp;#039;table&amp;#039;):addClass(&amp;#039;wikitable sortable sticky-header align-center-2 align-right-3 align-right-4 align-center-5 align-center-6 align-right-7 align-center-8 align-right-9&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	-- tableCaption is used only for patches&lt;br /&gt;
	local additionalCaption = &amp;#039;&amp;#039;&lt;br /&gt;
	local outputType = &amp;#039;Run&amp;#039;&lt;br /&gt;
	if(tableCaption ~= nil) then&lt;br /&gt;
		outputType = &amp;#039;Patch&amp;#039;&lt;br /&gt;
		additionalCaption = tableCaption .. &amp;#039; at &amp;#039;&lt;br /&gt;
		header:addClass(&amp;#039;mw-collapsible mw-collapsed&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	header:tag(&amp;#039;caption&amp;#039;):wikitext(&amp;#039;Herb yield at &amp;#039; .. additionalCaption .. scp(&amp;#039;Farming&amp;#039;, farmingLevel, true))&lt;br /&gt;
	row = header:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	row:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Herb&amp;#039;):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(scp(&amp;#039;Farming&amp;#039;) .. &amp;#039;Level&amp;#039;):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Seed cost&amp;#039;):done()&lt;br /&gt;
	if(sell == &amp;#039;Clean&amp;#039; or sell == &amp;#039;Grimy&amp;#039;) then&lt;br /&gt;
		row:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Herb price&amp;#039;):done()&lt;br /&gt;
	else&lt;br /&gt;
		row:tag(&amp;#039;th&amp;#039;):wikitext(scp(&amp;#039;Herblore&amp;#039;) .. &amp;#039;Level&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Unfinished potion&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Unf potion price&amp;#039;):done()&lt;br /&gt;
	end&lt;br /&gt;
	row:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Chance of Death&amp;#039;):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Expected Herbs&amp;#039;):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Profit per &amp;#039; .. outputType):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;XP per &amp;#039; .. outputType):done()&lt;br /&gt;
		:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;GP/XP&amp;#039;):done()&lt;br /&gt;
	return header&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createRow(herbName, herbData, deathChance, isResurrectWorth, sell, yield, profit, xp, gpPerXp)&lt;br /&gt;
	local row = mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local herbType, herbPrice, potionPrice&lt;br /&gt;
	if(herbName == &amp;#039;Goutweed&amp;#039;) then&lt;br /&gt;
		herbType = &amp;#039;Goutweed&amp;#039;&lt;br /&gt;
		herbPrice = math.ceil(goutweedSanfewExchange)&lt;br /&gt;
	elseif(sell == &amp;#039;Clean&amp;#039;) then&lt;br /&gt;
		herbType = herbName&lt;br /&gt;
		herbPrice = gePrices[herbType]&lt;br /&gt;
	elseif(sell == &amp;#039;Grimy&amp;#039;) then&lt;br /&gt;
		herbType = &amp;#039;Grimy &amp;#039; .. herbName:lower()&lt;br /&gt;
		herbPrice = gePrices[herbType]&lt;br /&gt;
	elseif(sell == &amp;#039;Unfinished potion&amp;#039;) then&lt;br /&gt;
		herbType = herbName&lt;br /&gt;
		potionPrice = gePrices[UnfinishedPotions[herbType].potion]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	row:tag(&amp;#039;td&amp;#039;):wikitext(&amp;#039;[[File:&amp;#039; .. herbType .. &amp;#039;.png]] [[&amp;#039; .. herbType .. &amp;#039;|&amp;#039; .. herbName .. &amp;#039;]]&amp;#039;):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(herbData.level):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(coins(gePrices[herbData.seed])):done()&lt;br /&gt;
	&lt;br /&gt;
	if(herbName == &amp;#039;Goutweed&amp;#039; and sell == &amp;#039;Unfinished potion&amp;#039;) then&lt;br /&gt;
		row:tag(&amp;#039;td&amp;#039;):wikitext():addClass(&amp;#039;table-na nohighlight&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;):wikitext():addClass(&amp;#039;table-na nohighlight&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;):wikitext():addClass(&amp;#039;table-na nohighlight&amp;#039;):css(&amp;#039;border-right-width&amp;#039;, &amp;#039;medium&amp;#039;):done()&lt;br /&gt;
	elseif(sell == &amp;#039;Clean&amp;#039; or sell == &amp;#039;Grimy&amp;#039;) then&lt;br /&gt;
		row:tag(&amp;#039;td&amp;#039;):wikitext(coins(herbPrice)):css(&amp;#039;border-right-width&amp;#039;, &amp;#039;medium&amp;#039;):done()&lt;br /&gt;
	elseif(sell == &amp;#039;Unfinished potion&amp;#039;) then&lt;br /&gt;
		row:tag(&amp;#039;td&amp;#039;):wikitext(UnfinishedPotions[herbType].herblore):done()&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;):wikitext(&amp;#039;[[File:&amp;#039; .. UnfinishedPotions[herbType].potion .. &amp;#039;.png]] [[&amp;#039; .. UnfinishedPotions[herbType].potion .. &amp;#039;]]&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;td&amp;#039;):wikitext(coins(potionPrice)):css(&amp;#039;border-right-width&amp;#039;, &amp;#039;medium&amp;#039;):done()&lt;br /&gt;
	end&lt;br /&gt;
			&lt;br /&gt;
	row:tag(&amp;#039;td&amp;#039;):wikitext(tonumber(string.format(&amp;quot;%.3f&amp;quot;, deathChance * 100)) .. &amp;#039;%&amp;#039; .. (not isResurrectWorth and warningTag or &amp;#039;&amp;#039;)):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(tonumber(string.format(&amp;quot;%.3f&amp;quot;, yield))):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(coins(profit)):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(tonumber(string.format(&amp;quot;%.1f&amp;quot;, xp))):done()&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;):wikitext(coins(gpPerXp)):done()&lt;br /&gt;
	return row&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- From [[Farming#Variable crop yield]] and [[Talk:Farming#Yield rates of various crops]]&lt;br /&gt;
function generateEstimatedYield(farmingLevel, lowCTS, highCTS, harvestLives, itemBonus, diaryBonus, attasBonus)&lt;br /&gt;
	local lowCTSFinal = math.floor(lowCTS * (1 + itemBonus))&lt;br /&gt;
	lowCTSFinal = lowCTSFinal + diaryBonus&lt;br /&gt;
	lowCTSFinal = math.floor(lowCTSFinal * (1 + attasBonus))&lt;br /&gt;
	&lt;br /&gt;
	local highCTSFinal = math.floor(highCTS * (1 + itemBonus))&lt;br /&gt;
	highCTSFinal = highCTSFinal + diaryBonus&lt;br /&gt;
	highCTSFinal = math.floor(highCTSFinal * (1 + attasBonus))&lt;br /&gt;
	&lt;br /&gt;
	local chanceToSave = skillInterp(lowCTSFinal, highCTSFinal, farmingLevel)&lt;br /&gt;
    return harvestLives / (1 - chanceToSave)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- From [[Module:Skilling success chart]]&lt;br /&gt;
function skillInterp(low, high, level)&lt;br /&gt;
	local value = math.modf(low * (99 - level) / 98) + math.modf(high * (level - 1) / 98) + 1&lt;br /&gt;
	return math.min(math.max(value / 256, 0), 1)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local farmingLevel = paramTest.default_to(tonumber(args.farmingLevel), 1)&lt;br /&gt;
	local patchCount = paramTest.default_to(tonumber(args.patchCount), 1)&lt;br /&gt;
	local weissDiseaseFreePatch = yesNo(args.weissDiseaseFreePatch) or false&lt;br /&gt;
	local trollheimDiseaseFreePatch = yesNo(args.trollheimDiseaseFreePatch) or false&lt;br /&gt;
	local hosidiusDiseaseFreePatch = yesNo(args.hosidiusDiseaseFreePatch) or false&lt;br /&gt;
	local fortisDiseaseFreePatch = yesNo(args.fortisDiseaseFreePatch) or false&lt;br /&gt;
	local compostType = paramTest.default_to(paramTest.ucflc(args.compostType), &amp;#039;None&amp;#039;)&lt;br /&gt;
	local useBottomlessCompostBucket = yesNo(args.useBottomlessCompostBucket) or false&lt;br /&gt;
	local useMagicSecateurs = yesNo(args.useMagicSecateurs) or false&lt;br /&gt;
	local useFarmingCape = yesNo(args.useFarmingCape) or false&lt;br /&gt;
	local animaType = paramTest.default_to(paramTest.ucflc(args.animaType), &amp;#039;None&amp;#039;)&lt;br /&gt;
	local kandarinDiary = paramTest.default_to(args.kandarinDiary, &amp;#039;None&amp;#039;)&lt;br /&gt;
	local kourendHardDiary = yesNo(args.kourendHardDiary) or false&lt;br /&gt;
	local useResurrectCrops = yesNo(args.useResurrectCrops) or false&lt;br /&gt;
	local magicLevel = paramTest.default_to(tonumber(args.magicLevel), 1)&lt;br /&gt;
	local sell = paramTest.default_to(args.sell, &amp;#039;Grimy&amp;#039;) -- Grimy, Clean, Unfinished potion&lt;br /&gt;
	&lt;br /&gt;
	local herbDataTable = {}&lt;br /&gt;
	for _, data in ipairs(farmingData) do&lt;br /&gt;
		if(data[&amp;#039;type&amp;#039;] == &amp;#039;Herb&amp;#039;) then&lt;br /&gt;
			herbDataTable[data.name] =  {&lt;br /&gt;
				[&amp;#039;level&amp;#039;] = data.level,&lt;br /&gt;
				[&amp;#039;xp&amp;#039;] = data.xp,&lt;br /&gt;
				[&amp;#039;plantXp&amp;#039;] = data.plantXp,&lt;br /&gt;
				[&amp;#039;seed&amp;#039;] = data.materials[1].name,&lt;br /&gt;
			}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local compostCostPerPatch = 0&lt;br /&gt;
	if(compostType ~= &amp;#039;None&amp;#039;) then&lt;br /&gt;
		compostCostPerPatch = useBottomlessCompostBucket and gePrices[compostType] * 0.5 or gePrices[compostType]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local costToResurrect = (gePrices[&amp;#039;Soul rune&amp;#039;] *  8) + (gePrices[&amp;#039;Nature rune&amp;#039;] *  12) + (gePrices[&amp;#039;Blood rune&amp;#039;] *  8) + (gePrices[&amp;#039;Earth rune&amp;#039;] *  25)&lt;br /&gt;
	-- Resurrect Crops spell, level 78 = 50% and level 99 = 75%&lt;br /&gt;
	local chanceToResurrect = skillInterp(-111, 191, magicLevel)&lt;br /&gt;
	&lt;br /&gt;
	local itemBonus = 0&lt;br /&gt;
	if(useMagicSecateurs) then&lt;br /&gt;
		itemBonus = itemBonus + .1&lt;br /&gt;
	end&lt;br /&gt;
	if(useFarmingCape) then&lt;br /&gt;
		itemBonus = itemBonus + .05&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local kandarinDiaryBonus = 0&lt;br /&gt;
	if(kandarinDiary ~= &amp;#039;None&amp;#039;) then&lt;br /&gt;
		kandarinDiaryBonus = tonumber(kandarinDiary:match(&amp;quot;%d+&amp;quot;)) / 100&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local kourendDiaryBonus = kourendHardDiary and 0.05 or 0&lt;br /&gt;
&lt;br /&gt;
	local attasBonus = animaType == &amp;#039;Attas&amp;#039; and 0.05 or 0&lt;br /&gt;
	-- Iasor lowers death rates by 80%&lt;br /&gt;
	local deathRateModifier = animaType == &amp;#039;Iasor&amp;#039; and 0.2 or 1&lt;br /&gt;
&lt;br /&gt;
	-- All herbs default have 26/128 chance to die each stage. There are only 3 stages which can be diseased or die.&lt;br /&gt;
	---- This is actually 27, see [[Talk:Disease (Farming)]]&lt;br /&gt;
	local deathRatePerStage = (math.floor(math.floor(27 / compostChanceToLoseLifeReduction[compostType]) * deathRateModifier) + 1) / 128&lt;br /&gt;
	local patchSurvivalRate = (1 - deathRatePerStage)^3&lt;br /&gt;
	local patchDeathRate = 1 - patchSurvivalRate&lt;br /&gt;
	&lt;br /&gt;
	if(useResurrectCrops) then&lt;br /&gt;
		--\left (\sum_{i=2}^{n-1}\binom{n-1}{i}p^i \left(1-P\right)^{\left(n-1)-i\right )} \right )R&lt;br /&gt;
		patchDeathRate = ((1-(1-deathRatePerStage)^4)*(1-chanceToResurrect)) + (6 * deathRatePerStage^2 * (1 - deathRatePerStage)^2) + (4 * deathRatePerStage^3 * (1-deathRatePerStage)) + deathRatePerStage^4&lt;br /&gt;
		patchSurvivalRate = 1 - patchDeathRate&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local patches = {}&lt;br /&gt;
	-- Hard Kourend Diary completion&lt;br /&gt;
	if(kourendHardDiary and hosidiusDiseaseFreePatch and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(patches, {&lt;br /&gt;
			createHeader(farmingLevel, sell, &amp;#039;Hosidius (Protected, +&amp;#039; .. kourendDiaryBonus * 100 .. &amp;#039;% Diary bonus)&amp;#039;),&lt;br /&gt;
			patchCount = 1,&lt;br /&gt;
			yieldBonus = percentToValueIncreaseCTS[tostring(kourendDiaryBonus)],&lt;br /&gt;
			protected = true,&lt;br /&gt;
		})&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	-- Protected patches, includes Kourend if hard diary is not completed.&lt;br /&gt;
	local protectedNames = {}&lt;br /&gt;
	if(weissDiseaseFreePatch and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(protectedNames, &amp;#039;Weiss&amp;#039;)&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	if(trollheimDiseaseFreePatch and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(protectedNames, &amp;#039;Trollheim&amp;#039;)&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	if(fortisDiseaseFreePatch and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(protectedNames, &amp;#039;Civitas illa Fortis&amp;#039;)&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	--	Only include if it is not already included above&lt;br /&gt;
	if(not kourendHardDiary and hosidiusDiseaseFreePatch and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(protectedNames, &amp;#039;Hosidius&amp;#039;)&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	if(#protectedNames &amp;gt; 0) then&lt;br /&gt;
		table.insert(patches, {&lt;br /&gt;
			createHeader(farmingLevel, sell, listToText(protectedNames, &amp;#039;, &amp;#039;, &amp;#039; and &amp;#039;) .. &amp;#039; (Protected)&amp;#039;),&lt;br /&gt;
			patchCount = #protectedNames,&lt;br /&gt;
			yieldBonus = 0,&lt;br /&gt;
			protected = true,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
	-- Kandarin patch with Kandarin Diary completion&lt;br /&gt;
	if(kandarinDiaryBonus &amp;gt; 0 and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(patches, {&lt;br /&gt;
			createHeader(farmingLevel, sell, &amp;#039;Kandarin (+&amp;#039; .. kandarinDiaryBonus * 100 .. &amp;#039;%  Diary bonus)&amp;#039;),&lt;br /&gt;
			patchCount = 1,&lt;br /&gt;
			yieldBonus = percentToValueIncreaseCTS[tostring(kandarinDiaryBonus)],&lt;br /&gt;
			protected = false,&lt;br /&gt;
		})&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	-- Farming Guild patch with diary&lt;br /&gt;
	if(kourendHardDiary and patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(patches, {&lt;br /&gt;
			createHeader(farmingLevel, sell, &amp;#039;Farming Guild (+&amp;#039; .. kourendDiaryBonus * 100 .. &amp;#039;% Diary bonus)&amp;#039;),&lt;br /&gt;
			patchCount = 1,&lt;br /&gt;
			yieldBonus = percentToValueIncreaseCTS[tostring(kourendDiaryBonus)],&lt;br /&gt;
			protected = false,&lt;br /&gt;
		})&lt;br /&gt;
		patchCount = patchCount - 1&lt;br /&gt;
	end&lt;br /&gt;
	-- The rest of the patches, no additional yield and no protection&lt;br /&gt;
	if(patchCount &amp;gt; 0) then&lt;br /&gt;
		table.insert(patches, {&lt;br /&gt;
			createHeader(farmingLevel, sell, patchCount .. &amp;#039; standard patch&amp;#039; .. (patchCount &amp;gt; 1 and &amp;#039;es&amp;#039; or &amp;#039;&amp;#039;)), -- If more than 1 patch, pluralise&lt;br /&gt;
			patchCount = patchCount,&lt;br /&gt;
			yieldBonus = 0,&lt;br /&gt;
			protected = false,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local runRet = createHeader(farmingLevel, sell)&lt;br /&gt;
	local patchRet = &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	for _, herb in ipairs(herbs) do&lt;br /&gt;
		&lt;br /&gt;
		local seedCost = gePrices[herbDataTable[herb.name].seed]&lt;br /&gt;
		local isRessurectWorth = true&lt;br /&gt;
		if(useResurrectCrops) then&lt;br /&gt;
			 isRessurectWorth = seedCost * chanceToResurrect &amp;gt; costToResurrect&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local totalYield, totalProfit, totalXp = 0, 0, 0&lt;br /&gt;
		local additiveDeathRate, patchCounter = 0, 0&lt;br /&gt;
		&lt;br /&gt;
		for _, patch in ipairs(patches) do&lt;br /&gt;
			local deathRate = patch.protected == true and 0 or patchDeathRate&lt;br /&gt;
			local patchYield = generateEstimatedYield(farmingLevel, herb.lowCTS, herb.highCTS, 3 + compostLifeValue[compostType], itemBonus, patch.yieldBonus, attasBonus)&lt;br /&gt;
			local truePatchYield = patch.protected == true and patchYield or patchYield * patchSurvivalRate&lt;br /&gt;
			local patchCost = compostCostPerPatch + gePrices[herbDataTable[herb.name].seed] + ((patch.protected ~= true and useResurrectCrops == true) and costToResurrect * deathRate or 0)&lt;br /&gt;
			local waterVialCost = sell == &amp;#039;Unfinished potion&amp;#039; and gePrices[&amp;#039;Vial of water&amp;#039;] or 0&lt;br /&gt;
			local profitItemName = &amp;#039;&amp;#039;&lt;br /&gt;
			if(sell == &amp;#039;Grimy&amp;#039;) then&lt;br /&gt;
				profitItemName = &amp;#039;Grimy &amp;#039; .. herb.name:lower()&lt;br /&gt;
			elseif(sell == &amp;#039;Clean&amp;#039; or herb.name == &amp;#039;Goutweed&amp;#039;) then&lt;br /&gt;
				profitItemName = herb.name&lt;br /&gt;
			elseif(sell == &amp;#039;Unfinished potion&amp;#039;) then&lt;br /&gt;
				profitItemName = UnfinishedPotions[herb.name].potion&lt;br /&gt;
			end&lt;br /&gt;
			local grossProfit = herb.name == &amp;#039;Goutweed&amp;#039; and goutweedSanfewExchange or (gePrices[profitItemName]) * truePatchYield&lt;br /&gt;
			local patchProfit = grossProfit - patchCost - (truePatchYield * waterVialCost)&lt;br /&gt;
			local patchXp = (truePatchYield * herbDataTable[herb.name].xp) + (herbDataTable[herb.name].plantXp * patchSurvivalRate)&lt;br /&gt;
			local gpPerXp = patchProfit / patchXp&lt;br /&gt;
			patch[1]:node(createRow(herb.name, herbDataTable[herb.name], deathRate, isRessurectWorth, sell, truePatchYield, patchProfit, patchXp, gpPerXp))&lt;br /&gt;
			totalYield = totalYield + (truePatchYield * patch.patchCount)&lt;br /&gt;
			totalProfit = totalProfit + (patchProfit * patch.patchCount)&lt;br /&gt;
			totalXp = totalXp + (patchXp * patch.patchCount)&lt;br /&gt;
			additiveDeathRate = additiveDeathRate + (deathRate * patch.patchCount)&lt;br /&gt;
			patchCounter = patchCounter + patch.patchCount&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		runRet:node(createRow(herb.name, herbDataTable[herb.name], additiveDeathRate/patchCounter, isRessurectWorth, sell, totalYield, totalProfit, totalXp, totalProfit/totalXp))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for _, v in ipairs(patches) do&lt;br /&gt;
		patchRet = patchRet .. tostring(v[1])&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local patchCountWarning = &amp;#039;&amp;#039;&lt;br /&gt;
	-- This is to catch weird situations caused by inability to affect calculator buttons. E.g. It is not possible to have 9 patches calculated correctly with one or both of these disabled.&lt;br /&gt;
	if(8 + (trollheimDiseaseFreePatch and 1 or 0) +  (weissDiseaseFreePatch and 1 or 0) + (fortisDiseaseFreePatch and 1 or 0) &amp;lt; tonumber(args.patchCount)) then&lt;br /&gt;
		patchCountWarning = &amp;#039;&amp;lt;b&amp;gt;Warning:&amp;lt;/b&amp;gt; Your currently disabled disease-free patches make the \&amp;#039;\&amp;#039;Total herb patches\&amp;#039;\&amp;#039; option inaccurate.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return patchCountWarning .. tostring(runRet) .. (useResurrectCrops and warningNote or &amp;#039;&amp;#039;) .. &amp;#039;Click \&amp;#039;Show\&amp;#039; on the tables to view patch breakdowns:\n&amp;#039; .. tostring(patchRet)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- DEBUG&lt;br /&gt;
-- args = {[&amp;#039;farmingLevel&amp;#039;] = 99, [&amp;#039;patchCount&amp;#039;] = 10, [&amp;#039;weissDiseaseFreePatch&amp;#039;] = true, [&amp;#039;trollheimDiseaseFreePatch&amp;#039;] = true, [&amp;#039;hosidiusDiseaseFreePatch&amp;#039;] = true, [&amp;#039;compostType&amp;#039;] = &amp;#039;Ultracompost&amp;#039;, [&amp;#039;useBottomlessCompostBucket&amp;#039;] = true, [&amp;#039;useMagicSecateurs&amp;#039;] = true, [&amp;#039;useFarmingCape&amp;#039;] = true, [&amp;#039;animaType&amp;#039;] = &amp;#039;Iasor&amp;#039;, [&amp;#039;kandarinDiary&amp;#039;] = &amp;#039;15% — Elite Kandarin Diary&amp;#039;, [&amp;#039;kourendHardDiary&amp;#039;] = true, [&amp;#039;useResurrectCrops&amp;#039;] = true, [&amp;#039;magicLevel&amp;#039;] = 99 } &lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	--mw.logObject(args)&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>