Module:TamingTable

local p = {} function p.creature( f ) local args = f:getParent.args local levels = {} local creature = args[1] -- if creature was not given, take it from PAGENAME if creature == nil then creature = f.args[1] end

local creatureData = mw.loadData( 'Module:TamingTable/creatures' ) if creatureData[creature] ~= nil then for i, level in ipairs(args) do	if i ~= 1 then table.insert(levels,level) end end

if table.getn(levels) == 0 then levels = {1,30,60,90,120} end local foodData = mw.loadData( 'Module:TamingTable/food' ) local tables = {}

-- initialize taming variables local affinityNeeded, totalTorpor, torporDeplPS, foodPiecesNeeded, seconds, foodAffinity, foodValue, wakeAffinityMult, wakeFoodDeplMult, foodname, foodBase1, foodIncrease, wakingTameFeedInterval, waitTime = 0, 0, 0, 0, 0, 0, 0, 1, 1, '', 1, 0, 15, 0

-- test if creature is tamend non-violently, then use wakeTame multiplicators local nonViolent = false if (creatureData[creature].nonViolentTame ~= nil and creatureData[creature].nonViolentTame == 1) then nonViolent = true if creatureData[creature].wakeAffinityMult ~= nil then wakeAffinityMult = creatureData[creature].wakeAffinityMult end if creatureData[creature].wakeFoodDeplMult ~= nil then wakeFoodDeplMult = creatureData[creature].wakeFoodDeplMult end if creatureData[creature].foodBase1 ~= nil and creatureData[creature].foodBase1 > 0 then foodBase1 = creatureData[creature].foodBase1 end if creatureData[creature].foodIncrease ~= nil then foodIncrease = creatureData[creature].foodIncrease end if creatureData[creature].wakingTameFeedInterval ~= nil then wakingTameFeedInterval = creatureData[creature].wakingTameFeedInterval end end -- creature need heavy weapon knockout? (like rock elemental, titnaosaur) local heavyWeaponKnockout = false if (creatureData[creature].heavyWeaponKnockout ~= nil and creatureData[creature].heavyWeaponKnockout == 1) then heavyWeaponKnockout = true end local magical = false if (creatureData[creature].magical ~= nil and creatureData[creature].magical == 1) then magical = true end for _,level in ipairs(levels) do	local headerCols = ''

if nonViolent then headerCols = '! Feeding Interval \n! Time' else -- total torpor for level totalTorpor = creatureData[creature].torpor1 + creatureData[creature].torporIncrease * (level-1)

-- torpor depletion per second for level -- here an exponential approximation of the torpor Depletion is used, credits to http://crumplecorn.com/content/taming-calculator if creatureData[creature].torporDepletionPS0 ~= nil then torporDeplPS = creatureData[creature].torporDepletionPS0 + math.exp(0.800403041 * math.log(level - 1)) / (22.39671632 / creatureData[creature].torporDepletionPS0); else torporDeplPS = 0 end

if torporDeplPS > 0 then headerCols = '! \n! \n! \n! Time' else headerCols = '! Time' end end local rows = {'{| class="wikitable" data-description="Taming Table Level '..level..'"\n|-\n! colspan="2" | Level '..level..'\n'..headerCols..''}

if creatureData[creature].affinityNeeded0 ~= nil and creatureData[creature].affinityIncrease ~= nil and torporDeplPS ~= nil then affinityNeeded = creatureData[creature].affinityNeeded0 + creatureData[creature].affinityIncrease * level;

-- foodname for display foodname = ''

-- how much food/resources of the different kinds that this creature eats is needed for _,food in ipairs(creatureData[creature].eats) do		local cols = {} foodAffinity = 0 foodValue = 0 if food == 'Kibble' then foodname = 'Kibble ('..creatureData[creature].favoriteKibble..' Egg)' else foodname = food end -- check if creature handles this food in a special way (e.g. scorpions not liking raw meat as much) if (creatureData[creature].specialFoodValues ~= nil and creatureData[creature].specialFoodValues[food] ~= nil) then if creatureData[creature].specialFoodValues[food].affinity ~= nil then foodAffinity = creatureData[creature].specialFoodValues[food].affinity end if creatureData[creature].specialFoodValues[food].value ~= nil then foodValue = creatureData[creature].specialFoodValues[food].value end end if foodData[food] ~= nil then if foodAffinity == 0 then foodAffinity = foodData[food].affinity end if foodValue == 0 then foodValue = foodData[food].foodValue end end if (foodAffinity > 0 and foodValue > 0) then -- consider wake taming multiplicators (non-violent taming) foodAffinity = foodAffinity * wakeAffinityMult foodValue = foodValue * wakeFoodDeplMult

-- amount of food foodPiecesNeeded = math.ceil(affinityNeeded/foodAffinity) -- time to eat needed food if nonViolent then -- there is a (long) wait time between the first and second feeding, because the food value of the creature has to drop below 90% if foodPiecesNeeded > 1 then -- Assume 30% of points spend to increase food, need to eat 10% of food to reach 90% local foodToEat = foodBase1 * (1 + foodIncrease * math.ceil((level - 1) * 0.3)) * 0.1 waitTime = math.max(wakingTameFeedInterval, foodToEat / (creatureData[creature].foodConsumptionBase * creatureData[creature].foodConsumptionMult * wakeFoodDeplMult)) seconds = math.ceil((foodPiecesNeeded - 1) * foodValue / (creatureData[creature].foodConsumptionBase * creatureData[creature].foodConsumptionMult) + waitTime) else seconds = 0 end else seconds = math.ceil(foodPiecesNeeded * foodValue / (creatureData[creature].foodConsumptionBase * creatureData[creature].foodConsumptionMult)) end -- hack to correct basilosaurus' taming times if creatureData[creature].resultCorrection ~= nil then seconds = seconds * creatureData[creature].resultCorrection end

table.insert(cols,'|style="border-right-width:0"| '..foodname..'') table.insert(cols,';border-left-width:0"|'..foodPiecesNeeded)           if nonViolent then              -- feeding intervall (only approximately (mean), exact numbers seem to be more complicated because of inital longer pause)              -- the last feeded food grants the tame instantly, so subtract one of the needed pieces for the time              local feedingInterval = 0              if foodPiecesNeeded > 1 then                feedingInterval = (seconds-waitTime)/(foodPiecesNeeded)              end			table.insert(cols,'"|'..os.date("!%M:%S",feedingInterval)) else -- extra needed torpor to eat needed food local torporNeeded = math.ceil(torporDeplPS * seconds - totalTorpor) if torporNeeded < 0 then torporNeeded = 0 end

-- only display number of narcos if columns exist if torporDeplPS > 0 then -- amount of Narcoberries (give 7.5 torpor each over 3s) table.insert(cols,'"|'..math.ceil(torporNeeded/(7.5+3*torporDeplPS)))				-- amount of Narcotics (give 40 each over 8s)				table.insert(cols,'"|'..math.ceil(torporNeeded/(40+8*torporDeplPS))) -- amount of Bio Toxins (give 80 each over 16s) table.insert(cols,'"|'..math.ceil(torporNeeded/(80+16*torporDeplPS)))			end			end			-- needed Time to eat			table.insert(cols,'"|'..math.floor(seconds/3600)..':'..os.date("!%M:%S",seconds))

table.insert(rows,table.concat(cols,'\n| align="right" style="min-width:2.8em'))		end		end	end

local torporInfoRows = '' if not nonViolent then -- set per dino, per weapon damage modifier to 1 and test if a different value is defined clubModifier, slingshotModifier, bowModifier, crossbowModifier, rifleModifier = 1, 1, 1, 1, 1 if creatureData[creature].clubModifier ~= nil then clubModifier = creatureData[creature].clubModifier end if creatureData[creature].bowModifier ~= nil then bowModifier = creatureData[creature].bowModifier end if creatureData[creature].crossbowModifier ~= nil then crossbowModifier = creatureData[creature].crossbowModifier end if creatureData[creature].rifleModifier ~= nil then rifleModifier = creatureData[creature].rifleModifier end if heavyWeaponKnockout then --		local ballistaTorpor = creatureData[creature].heavyWeaponTorporValue['ballistaBolt'] local boulderTorpor = creatureData[creature].heavyWeaponTorporValue['boulder'] local rocketTorpor = creatureData[creature].heavyWeaponTorporValue['rocket'] local homingRocketTorpor = creatureData[creature].heavyWeaponTorporValue['homingRocket'] local cannonballTorpor = creatureData[creature].heavyWeaponTorporValue['cannonball'] -- 		local ballistaBoltsNeeded = nil local bouldersNeeded = nil local rocketsNeeded = nil local homingRocketsNeeded = nil local cannonballsNeeded = nil

if (totalTorpor/ballistaTorpor) then ballistaBoltsNeeded = ' N/A ' else ballistaBoltsNeeded = math.ceil(totalTorpor/ballistaTorpor) end --		if (totalTorpor/boulderTorpor == 0) then bouldersNeeded = ' N/A ' else bouldersNeeded = math.ceil(totalTorpor/boulderTorpor) end --		if (totalTorpor/rocketTorpor == 0) then rocketsNeeded = ' N/A ' else rocketsNeeded = math.ceil(totalTorpor/rocketTorpor) end --		if (totalTorpor/homingRocketTorpor == 0) then homingRocketsNeeded = ' N/A ' else homingRocketsNeeded = math.ceil(totalTorpor/homingRocketTorpor) end --		if (totalTorpor/cannonballTorpor == 0) then cannonballsNeeded = ' N/A ' else cannonballsNeeded = math.ceil(totalTorpor/cannonballTorpor) end torporInfoRows = '\n|-\n| colspan="6" align="right" | KO : × ' ..ballistaBoltsNeeded.. '; × '		..bouldersNeeded.. '; × '		..rocketsNeeded.. '; × '		..homingRocketsNeeded.. '; × '		..cannonballsNeeded -- print torpor depletion per s		if torporDeplPS > 0 then torporInfoRows = torporInfoRows .. '\n|- style="font-size:0.8em"\n| colspan="6" align="right" | Torpidity-depletion: '..(math.ceil(100*torporDeplPS)/100)..' / s, Time until all torpidity is depleted: '..os.date("!%X", totalTorpor/torporDeplPS) end

elseif not heavyWeaponKnockout then -- print needed tranq arrows needed to ko creature. -- Bow-arrow causes 25.5 dmg, tranqMultiplier are 2+2.5=4.5 ==> 114.75 Torpor/arrow. (25.5 dmg) -- crossbow 15 dmg * 4.5 ==> 67.5 torpor (15 dmg) -- slingshot: 2 dmg, stone-tranq-mult: 2 + 2.5 = 4.5 ==> 9 torpor (2 dmg) -- wooden club: 7 dmg, mult 2 ==> 14 torpor (7 dmg) -- longneck dart: 341 * 2 = 682 torpor (341 dmg) -- magic bow: 76.5 * 3 = 229.5 torpor (76.5 dmg) -- magic crossbow: 45 * 3 = 135 torpor (45 dmg) if magical then torporInfoRows = '\n|-\n| colspan="6" align="right" | KO : × ' ..math.ceil(totalTorpor/(229.5*bowModifier)).. '; × '			..math.ceil(totalTorpor/(135*crossbowModifier)) else torporInfoRows = '\n|-\n| colspan="6" align="right" | KO : × ' ..math.ceil(totalTorpor/(14*clubModifier)).. '; × '			..math.ceil(totalTorpor/(9*slingshotModifier)).. '; × '			..math.ceil(totalTorpor/(114.75*bowModifier)).. '; × '			..math.ceil(totalTorpor/(67.5*crossbowModifier)).. '; × '			..math.ceil(totalTorpor/(682*rifleModifier)) end -- print torpor depletion per s		if torporDeplPS > 0 then torporInfoRows = torporInfoRows .. '\n|- style="font-size:0.8em"\n| colspan="6" align="right" | Torpidity-depletion: '..(math.ceil(100*torporDeplPS)/100)..' / s, Time until all torpidity is depleted: '..os.date("!%X", totalTorpor/torporDeplPS) end end end

table.insert(tables,table.concat(rows,'\n|-\n')..torporInfoRows..'\n|}') end return ' \n'..table.concat(tables,'\n \n')..'\n ' else return ' ''Error: No taming-data for "'..creature..'" found. If the current page is not a creature-page, write the wanted creature as first parameter. Use only the common name, found on the creature\'s dossier.''' end end return p