--
-- Mod: FS19_RealLifeNumbers by Kaj-Aage Henneberg "Ki", ArmChairFarming
-- Script: RealNumbersCropYield by Kaj-Aage Henneberg "Ki", ArmChairFarming
-- e-mail: kaj-aage.henneberg@outlook.dk
-- Download: www.modhoster.com
-- All rights reserved.
-- Version 1.1.4.0
-- 30.11.2018 - 29.06.2019

-- Names for FillTypes

-- WHEAT BARLEY OAT CANOLA SUNFLOWER SOYBEAN MAIZE POTATO SUGARBEET OILSEEDRADISH
-- MANURE SEEDS FORAGE FORAGE_MIXING CHAFF WOODCHIPS SILAGE
-- STRAW GRASS_WINDROW DRYGRASS_WINDROW SUGARCANE FERTILIZER PIGFOOD LIME
-- WOOL TREESAPLINGS EGG
-- MILK FUEL WATER DIESEL DEF
-- LIQUIDFERTILIZER HERBICIDE
-- CHAFF GRASS_WINDROW
-- LIQUIDMANURE DIGESTATE
-- COW_TYPE_BRAHMAN_GREY COW_TYPE_BRAHMAN_LIGHT_BROWN COW_TYPE_BRAHMAN_WHITE
-- COW_TYPE_BRAHMAN_BROWN COW_TYPE_BROWN COW_TYPE_BROWN_WHITE COW_TYPE_BLACK
-- COW_TYPE_BLACK_WHITE
-- SHEEP_TYPE_WHITE SHEEP_TYPE_BROWN SHEEP_TYPE_BLACK_WHITE SHEEP_TYPE_BLACK
-- PIG_TYPE_RED PIG_TYPE_WHITE PIG_TYPE_BLACK_WHITE PIG_TYPE_BLACK
-- CHICKEN_TYPE_BLACK CHICKEN_TYPE_WHITE CHICKEN_TYPE_BROWN CHICKEN_TYPE_ROOSTER

-- FruitType indices

	-- WHEAT :: 1, BARLEY :: 2, OAT :: 3, COTTON :: 4, CANOLA :: 5, SUNFLOWER :: 6,
	-- SOYBEAN :: 7, MAIZE :: 8, POTATO :: 9, SUGARBEET :: 10, OILSEEDRADISH :: 11,
	-- POPLAR :: 12, GRASS :: 13, DRYGRASS :: 14, SUGARCANE :: 15, WEED :: 16


--[[

	Verion 1.1.0.0
	
	Data format has changed in order to take multifruit maps into account. It is intended, that the modifications
	can handle maps with fruit types, which are not defined in RealNumbersInitialization. For these fruits,	
	parameter values defined by the map maker are used. Often this will be clear in the log file by a larger
	yield and a larger sell price. The mod user can make an entry for the new fruit into the script  
	RealNumbersInitialization by copying the format of another fruit type and change the fruit name and 
	parameter values. Place the new fruit in alphabetic order to facilitate later search for a particular fruit.
	
	Calculated data for seed usage and predicted crop income have been merged into this script.

Crop mass density

	Crop mass density (kg/Liter) varies as a function of moisture content. Different sources will therefore
	provide slightly different numbers. The majority of the numbers listed above are taken from
	The agricultural service of the province of Alberta, Canada.

	Be aware that Farmingsimulator requires density numbers in (metric) Tonne/Liter. Hence the numbers listed
	above is divided by 1000 when assigning the value to massPerLiter.

	Crop mass density is considered independent of geographical location.

Crop Yield

	Crop yield is assumed to be dependent on geographical location.

	Numbers for crop yield are given in a number of different units.
	EUROSTATS provides yield in	multiples of 100 kg/hectare or Tonne/hectare
	US National Agricultural Statistics Service uses lb/acre, bushels/acre, cwt/acre, ton/acre.
	Conversion to Liter/ha is required and from there to Liters/square meters.
	The following conversion numbers are used:

		1 bushel = 35.239072 Liters
		1 acre = 0.404685642 hectares
		1 CWT = 45.35924 kg

	All density numbers in the cropYield list is provided in multiples of 100kg/ha. The cropDensity
	values are used to convert cropYield numbers to Liters/square meter.

	The base yield X set in the game must be calculated from the national/regional yield Y.

	The help suggests that application of lime and fertilizer will add 15% and 25% respectively. Thus,
	one application of lime and two applications of fertilizer should give 65% increase relative to base
	yield, suggesting that X + 0.65*X = Y, that is X = Y/1.65.

	However, tests suggest that this is not how it works. It appear that base yield is the minimum yield, you
	can get if you neglect to plough, remove weed, lime and fertilizer. Doing all this chores will add 100 %
	to the base yield. It seems therefore that X + 1*X = 2 X = Y, or X = Y/2. For this reason the parameter
	gameCorrection = 1/2, not 1/1.65 as one would expect.

	To include natural variations in crop yield, the yield for each crop is scaled by a randomness factor.
	The randomness factor varies within +/- two standard deviations for the given crop. Some crops
	have a small yield fluctuation, others a larger fluctuation, all dependng on the crop and geographical
	location. The randomness factor changes at each game load. It is the value at harvet, that determines the
	obtained yield. If the harvest of a field is divided between several gameplays, different yield setting will
	be encountered for each gameplay. This may be taken to represent yield variation across the field.

	Random variation of the yield can be turned off by different values of

	randomness = 0  => randomness is off
	randomness = 1  => randomness is on

	If you want to calibrate yield, this is better done without randomness in the yield parameter. After
	calibration, randomness can be turned back on.

Windrow Yield

	Windrow yield for grain crops is about 80% of grain yield measured in kg/ha.
	Straw density is set to 0.13 kg/Liter

	Look in the log file for printed output from this script.

]]--

RealNumbersCropYield = {};


function RealNumbersCropYield:loadMap(name)
    local textWidth = 40; 					-- text width in log file
    local iFillType = 0;
	local iFruitType = 0;
	local Crop = "Empty";
	local idx = 0;
	local currency = "€";	-- or  "$" or "£"
	local bonusYield = 0;
	local baseYield = 0;
	local bonusWindrow = 0;
	local gameWindrow = 0;
	local lossWindrow = 0.05;
	local seedRate = 0;
	local price = 0;
	local bonusScale = 1.0;						-- for adding extra yield for perfect crop management
	local massScale = 1000;						-- FS uses Tonne/Liter for mass density
	local gameCorrection = RN.fieldWorkbaseYieldAdjustment;	-- scale factor to obtain base yield from bonus yield

	local randomYieldFactor = 1;				-- default value used if reading seed number fails
	local randomness = RN.randomness;			-- Set to 1 to turn randomness on, 0 to turn off
	local playTime = nil;
	local noPloughLoss = 0;
	local noWeedingLoss = 0;
	local LimeBonus = 0;
	local FertilizerBonus = 0;
	local grain = {};
	local rowgrain = {};
	local sugarbeet = {};
	local potato = {};
	local isDebug = RN.isDebug;  						-- Change to False when no printing to log file is desired
	local isDebug2 = false;

	local gameLevelYieldCorrection = RN.gameLevel.cropYieldCorrection;
	local Fruits = RN.fruits;							-- local copy of global variable
	local cropDensity = RN.cropDensity;					-- local copy of global variable
	local cropYield = RN.cropYield;						-- local copy of global variable
	local yieldRange = RN.yieldRange;					-- local copy of global variable
	local strawDensity = RN.commodityDensity.ROUNDBALE_WHEAT;
	local hayDensity = RN.commodityDensity.ROUNDBALE_DRYGRASS;
	local silageDensity = RN.commodityDensity.ROUNDBALE_GRASS;
	local TSM = RN.TSM;
	local plantsPerSqm = RN.plantsPerSqm;
	local germination = RN.germination;
	local seedPricePer100kg = RN.seedPricePer100kg;
	local cropPricePer100kg = RN.cropPricePer100kg;
	
	local gameMoneyUnit = g_i18n.moneyUnit;
	if gameMoneyUnit == 1 then 
        currency = "€";
	elseif gameMoneyUnit == 2 then 
        currency = "$";
	elseif gameMoneyUnit == 3 then 
        currency = "£";
	end;

	RN.bonusYieldPerHa = {};
	
-- FruitType indices

	-- WHEAT :: 1, BARLEY :: 2, OAT :: 3, COTTON :: 4, CANOLA :: 5, SUNFLOWER :: 6,
	-- SOYBEAN :: 7, MAIZE :: 8, POTATO :: 9, SUGARBEET :: 10, OILSEEDRADISH :: 11,
	-- POPLAR :: 12, GRASS :: 13, DRYGRASS :: 14, SUGARCANE :: 15, WEED :: 16

	print("\nFS19_RealLifeNumbers: RealNumbersCropYield active\n")

--[[ not used in v. 1.1
	grain.headerwidth = RN.grainHeaderwidth; 						-- m
	grain.workingspeed = RN.grainWorkingspeed;						-- kph
	grain.AreaPerSec = grain.headerwidth * grain.workingspeed/3.6;
	grain.hectarePer30Sec = 30 * grain.AreaPerSec/10000;

	rowgrain.headerwidth = RN.rowgrainHeaderwidth; 						-- m
	rowgrain.workingspeed = RN.rowgrainWorkingspeed;						-- kph
	rowgrain.AreaPerSec = rowgrain.headerwidth * rowgrain.workingspeed/3.6;
	rowgrain.hectarePer30Sec = 30 * rowgrain.AreaPerSec/10000;

	potato.headerwidth = RN.potatoHeaderwidth; 					-- m
	potato.workingspeed = RN.potatoWorkingspeed;					-- kph
	potato.AreaPerSec = potato.headerwidth * potato.workingspeed/3.6;
	potato.hectarePer30Sec = 30 * potato.AreaPerSec/10000;

	sugarbeet.headerwidth = RN.sugarbeetHeaderwidth; 					-- m
	sugarbeet.workingspeed = RN.sugarbeetWorkingspeed;					-- kph
	sugarbeet.AreaPerSec = sugarbeet.headerwidth * sugarbeet.workingspeed/3.6;
	sugarbeet.hectarePer30Sec = 30 * sugarbeet.AreaPerSec/10000;
--]]

	local savegameDirectory = g_currentMission.missionInfo.savegameDirectory;	-- works except when a new map is opened the first time
	if savegameDirectory ~= nil then
		local careerFile = savegameDirectory.."/careerSavegame.xml";
		if isDebug2 then print("careerFile : "..tostring(careerFile)); end;
		local xmlFile = loadXMLFile("careerFile", careerFile);
		local key = string.format("careerSavegame.statistics");
		if not hasXMLProperty(xmlFile, "careerSavegame") then
			if isDebug2 then print("Does not have XMLproperty"); end;
		end;
		playTime = 1000 * getXMLFloat(xmlFile, "careerSavegame.statistics.playTime");
	end;

	if playTime == nil then
		if isDebug2 then print("playTime is nil") end;
		randomness = 0;
	else
		local randomSeednumber = math.randomseed(playTime);
		if isDebug2 then print("playTime is "..playTime/1000); end;
		if isDebug2 then print("random number is "..math.random()); end;
	end;

-- create a list of fruits on the map and save in a table called fruitList

	local fruitList = {};
	for i,v in pairs(g_currentMission.fruitTypeManager.fruitTypes) do
		fruitList[i] = v.name;
--		print(v.name);
	end;
	
-- sort fruitList alphabetically and save in sortedFruits	

	local sortedFruits = {};
	for i,n in pairs(fruitList) do table.insert(sortedFruits,n); end;
	table.sort(sortedFruits);
	RN.sortedFruits = sortedFruits;
	for i,fruitName in ipairs(sortedFruits) do 
	--print(fruitName)



		iFillType = g_fillTypeManager:getFillTypeIndexByName(tostring(fruitName));
		iFruitType = g_fruitTypeManager:getFruitTypeIndexByFillTypeIndex(iFillType);

		if Fruits[fruitName] == nil then 	-- for undefined new fruitTypes, read map data into mod variables
			RN.yieldRange[fruitName] = 0;
			RN.cropDensity[fruitName] = massScale * g_currentMission.fillTypeManager.fillTypes[iFillType].massPerLiter;
			baseYield = g_currentMission.fruitTypeManager.fruitTypes[iFruitType].literPerSqm / gameLevelYieldCorrection;
			bonusYield = baseYield / gameCorrection;
			RN.cropYield[fruitName] = bonusYield * RN.cropDensity[fruitName]*10000/(bonusScale * randomYieldFactor * 100);
			RN.seedUsagePerSqm[fruitName] = g_currentMission.fruitTypeManager.fruitTypes[iFruitType].seedUsagePerSqm;
			RN.TSM[fruitName] = 0.;
			RN.plantsPerSqm[fruitName] = 0.;
			RN.germination[fruitName] = 1.;
			RN.seedDensity[fruitName] = RN.cropDensity[fruitName];
			RN.seedMassRatePerHa[fruitName] = 10000 * RN.seedUsagePerSqm[fruitName] * RN.seedDensity[fruitName];
			RN.cropPricePerLiter[fruitName] = g_currentMission.fillTypeManager.fillTypes[iFillType].pricePerLiter;
			RN.cropPricePer100kg[fruitName] = 100 * RN.cropPricePerLiter[fruitName]/RN.cropDensity[fruitName];
			RN.seedPricePer100kg[fruitName] = 1.5 * RN.cropPricePer100kg[fruitName];
			RN.seedCostPerHa[fruitName] = RN.seedPricePer100kg[fruitName] * RN.seedMassRatePerHa[fruitName]/100;
			RN.seedVolumeRatePerHa[fruitName] = RN.seedMassRatePerHa[fruitName]/RN.seedDensity[fruitName];
			RN.seedCostPerLiter[fruitName] = RN.seedDensity[fruitName] * RN.seedPricePer100kg[fruitName]/100;
			local minHarvestingGrowthState = g_fruitTypeManager.fruitTypes[iFruitType].minHarvestingGrowthState;
			RN.growthDays[fruitName] = g_fruitTypeManager.fruitTypes[iFruitType].growthStateTime * minHarvestingGrowthState/(24 * 3600000)		
		end;
		if (Fruits[fruitName] ~= nil) then 		-- defined fruits
			if RN.TSM[fruitName] > 0 then
				RN.seedMassRatePerHa[fruitName] = RN.seederCalibration[fruitName] * (RN.TSM[fruitName]*plantsPerSqm[fruitName])/RN.germination[fruitName];  -- kg/ha
			else
				RN.seedMassRatePerHa[fruitName] = 10000 * RN.seedUsagePerSqm[fruitName];
			end;
			RN.seedVolumeRatePerHa[fruitName] = RN.seedMassRatePerHa[fruitName]/RN.seedDensity[fruitName];
			RN.seedCostPerHa[fruitName] = RN.seedPricePer100kg[fruitName] * RN.seedMassRatePerHa[fruitName]/100;
			RN.seedUsagePerSqm[fruitName] = RN.seedMassRatePerHa[fruitName] / (10000 * RN.seedDensity[fruitName]);
			RN.cropPricePerLiter[fruitName] = RN.cropDensity[fruitName] * RN.cropPricePer100kg[fruitName]/100;
			RN.seedCostPerLiter[fruitName] = RN.seedDensity[fruitName] * RN.seedPricePer100kg[fruitName]/100;
			g_currentMission.fillTypeManager.fillTypes[iFillType].massPerLiter = RN.cropDensity[fruitName]/massScale;
			g_currentMission.fillTypeManager.fillTypes[iFillType].pricePerLiter = RN.cropPricePerLiter[fruitName];
			g_currentMission.fillTypeManager.fillTypes[iFillType].previousHourPrice = RN.cropPricePerLiter[fruitName];
			g_currentMission.fillTypeManager.fillTypes[iFillType].startPricePerLiter = RN.cropPricePerLiter[fruitName];		
		 
			
		end;

			Crop = tostring(fruitName);
			randomYieldFactor = 1 + randomness * 2*(math.random()-0.5) * RN.yieldRange[fruitName];
			local randomGrowthFactor = randomYieldFactor;
			bonusYield = bonusScale * randomYieldFactor * RN.cropYield[fruitName]*100/(RN.cropDensity[fruitName]*10000); --Real life yield in liters/sqm
			baseYield =  gameCorrection *  bonusYield;
			noPloughLoss = 10000 * baseYield * 0.15;				-- 15% loss
			noWeedingLoss = 10000 * baseYield * 0.2;				-- 20% loss
			LimeBonus = 10000 * baseYield * 0.15;					-- 15% gain
			FertilizerBonus = 10000 * baseYield * 0.25;				-- 25% gain
			RN.cropBonusYieldLitersPerHa[fruitName] = 10000 * bonusYield;
			g_currentMission.fillTypeManager.fillTypes[iFillType].massPerLiter = RN.cropDensity[fruitName]/massScale;
			g_currentMission.fruitTypeManager.fruitTypes[iFruitType].literPerSqm = gameLevelYieldCorrection * baseYield;
			local hasWindrow = false;
			if g_currentMission.fruitTypeManager.fruitTypes[iFruitType].hasWindrow ~= nil then
				hasWindrow = g_currentMission.fruitTypeManager.fruitTypes[iFruitType].hasWindrow;
				if hasWindrow then
					local windrowName = g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowName;
					if windrowName == "STRAW" then
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.strawYieldFactor * RN.cropYield[fruitName]*100/(strawDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_WHEAT;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE_WHEAT;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.strawYieldFactor * RN.cropYield[fruitName] * 100;					

					elseif windrowName == "RYE_WINDROW" then
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.strawYieldFactor * RN.cropYield[fruitName]*100/(strawDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_WHEAT;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE_WHEAT;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.strawYieldFactor * RN.cropYield[fruitName] * 100;					

					elseif windrowName == "DRYGRASS_WINDROW" then
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName]*100/(hayDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_DRYGRASS;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName] * 100;

					elseif windrowName == "DRYLUZERNE_WINDROW" then
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName]*100/(hayDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_DRYGRASS;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName] * 100;

					elseif windrowName == "LUZERNE_WINDROW" then
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName]*100/(silageDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_DRYGRASS;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName] * 100;

					else
--					if windrowName == "GRASS_WINDROW" then -- or CLOVER_WINDROW or some other Windrow
						bonusWindrow = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName]*100/(silageDensity*10000);
						gameWindrow = gameCorrection * bonusWindrow;
						g_currentMission.fruitTypeManager.fruitTypes[iFruitType].windrowLiterPerSqm = gameLevelYieldCorrection * gameWindrow;
						RN.windrowYieldLitersPerHa[fruitName] = 10000 * bonusWindrow;
						RN.numberRoundBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.ROUNDBALE_GRASS;
						RN.numberSquareBalesPerHa[fruitName] = RN.windrowYieldLitersPerHa[fruitName]/RN.commodityVolume.SQUAREBALE;
						RN.windrowYieldkgPerHa[fruitName] = (1-lossWindrow) * bonusScale * randomYieldFactor * RN.cropYield[fruitName] * 100;
					end;
					
				end;
			end;
			g_currentMission.fruitTypeManager.fruitTypes[iFruitType].seedUsagePerSqm = RN.seedUsagePerSqm[fruitName];
			local growthGameDays = RN.growthDays[fruitName] / (360/RN.gameDaysPerYear);
			local minHarvestingGrowthState = g_fruitTypeManager.fruitTypes[iFruitType].minHarvestingGrowthState;
			if minHarvestingGrowthState > 0 then
				g_fruitTypeManager.fruitTypes[iFruitType].growthStateTime = randomGrowthFactor * 24 * 3600000 * growthGameDays / minHarvestingGrowthState; -- milliseconds
			end;
			if fruitName == "WEED" then
				g_fruitTypeManager.fruitTypes[iFruitType].numGrowthStates = 3;
				g_fruitTypeManager.fruitTypes[iFruitType].growthStateTime = 24 * 3600000 * growthGameDays /1;		-- seems to have only one growth stage
				g_fruitTypeManager.fruitTypes[iFruitType].weed.growthStateTime = 24 * 3600000 * growthGameDays /1;	-- seems to have only one growth stage
			end;
			RN.cropPricePerHa[fruitName] = RN.cropBonusYieldLitersPerHa[fruitName] * RN.cropPricePerLiter[fruitName];
			RN.seedCostPerLiter[fruitName] = RN.seedDensity[fruitName] * RN.seedPricePer100kg[fruitName]/100

			
			if isDebug then
				myPrintFloat(Crop.." massPerLiter",RN.cropDensity[fruitName],textWidth," kg/L");
				myPrintFloat("Yield randomness scaling",randomYieldFactor,textWidth," ");
				myPrintFloat(Crop.." base yield",baseYield,textWidth," L/sqm");
				myPrint(Crop.." base yield",10000*baseYield,textWidth," L/Ha");
				myPrint(Crop.." no-plough loss",noPloughLoss,textWidth," L/Ha");
				myPrint(Crop.." no-weeding loss",noWeedingLoss,textWidth," L/Ha");
				myPrint(Crop.." liming gain",LimeBonus,textWidth," L/Ha");
				myPrint(Crop.." 1x fertilizing gain",FertilizerBonus,textWidth," L/Ha");
				myPrint(Crop.." max yield",RN.cropBonusYieldLitersPerHa[fruitName],textWidth," L/Ha");
				if growthGameDays > 0 then 
					myPrintFloat(Crop.." growth duration",growthGameDays,textWidth," game days");
				end;
				if hasWindrow then myPrint(Crop.." windrowLiterPerHa",10000* bonusWindrow,textWidth," L/Ha"); end;
				if hasWindrow then myPrintFloat(Crop.." round bales Per Ha",RN.numberRoundBalesPerHa[fruitName],textWidth," Bales/Ha"); end;
				if hasWindrow then myPrintFloat(Crop.." square bales Per Ha",RN.numberSquareBalesPerHa[fruitName],textWidth," Bales/Ha"); end;
				myPrintFloat(Crop.." seedMassPerLiter",RN.seedDensity[fruitName],textWidth," kg/L");
				myPrintFloat(Crop.." seedMassPerHa",RN.seedMassRatePerHa[fruitName],textWidth," kg/Ha");
				myPrintFloat(Crop.." seedVolumePerHa",RN.seedVolumeRatePerHa[fruitName],textWidth," L/Ha");
				myPrintFloat(Crop.." seedCostPerLiter",RN.seedCostPerLiter[fruitName],textWidth,currency.."/L");
				myPrintFloat(Crop.." seedCostPerHa",RN.seedCostPerHa[fruitName],textWidth,currency.."/Ha");		
				myPrint(Crop.." pricePer1000Liter",1000*RN.cropPricePerLiter[fruitName],textWidth,currency.."/1000 L");
				myPrint(Crop.." pricePerHa",RN.cropPricePerHa[fruitName],textWidth,currency.."/Ha\n");				

			end;			
	end;
end;


function RealNumbersCropYield:keyEvent(unicode, sym, modifier, isDown)
	local textWidth = 40;
	local isDebug = RN.isDebug;
	local currency = "€";	-- or  "$" or "£"	
	local gameMoneyUnit = g_i18n.moneyUnit;
	if gameMoneyUnit == 1 then 
        currency = "€";
	elseif gameMoneyUnit == 2 then 
        currency = "$";
	elseif gameMoneyUnit == 3 then 
        currency = "£";
	end;

--	local savegameDirectory = g_currentMission.missionInfo.savegameDirectory;	-- works only after savegame is present

--	if savegameDirectory ~= nil then

		if Input.isKeyPressed(Input.KEY_lalt) and Input.isKeyPressed(Input.KEY_r) and Input.isKeyPressed(Input.KEY_y) then

			local hour = g_currentMission.environment.currentHour;
			local minute = g_currentMission.environment.currentMinute;
			local money = g_currentMission.missionInfo.money;
			local economicDifficulty = g_currentMission.missionInfo.economicDifficulty;
			local currentDay = g_currentMission.environment.currentDay;
			local currentMap = tostring(g_currentMission.missionInfo.map.title.." "..g_currentMission.missionInfo.displayName);
			if isDebug then
				print("\nLeft Alt-ry pressed\n");
				if currentMap ~= nil then print("Map                   : "..currentMap); end;
				if money ~= nil then print("Money                 : "..money); end;
				if economicDifficulty ~=  nil then print("Economic difficulty   : "..economicDifficulty); end;
				if currentDay ~= nil then print("Current game day      : "..currentDay); end;
				if hour ~= nil or minute ~= nil then print("Time of day           : "..hour..":"..minute); end;
				print(" ");
			end;
--			if g_fruitTypeManager.fruitTypes ~= nil then
				if isDebug then print("\nCrop yield \n");end;
				for i,fruitName in ipairs(RN.sortedFruits) do
					myPrint(fruitName.." max yield",RN.cropBonusYieldLitersPerHa[fruitName],textWidth," L/Ha");
				end;

				if isDebug then print("\nCrop income \n");end;
				for i,fruitName in ipairs(RN.sortedFruits) do
					myPrint(fruitName.." max income",RN.cropPricePerHa[fruitName],textWidth,currency.."/Ha");
				end;

				if isDebug then print("\nCrop growth days \n");end;
				for i,fruitName in ipairs(RN.sortedFruits) do
					local growthGameDays = RN.growthDays[fruitName] / (360/RN.gameDaysPerYear);
					myPrintFloat(fruitName.." growth days",growthGameDays,textWidth," game days");
				end;
				
				if isDebug then print(" ");end;
				if currentDay ~= nil then print("Current game day      : "..currentDay); end;
				if isDebug then print(" ");end;
--			end;
		end;
--	else
--		if not RN.multiPlayer then print("No save game yet. Save the game, quit and reload"); end;
--	end;
end;
function RealNumbersCropYield:update(dt)
end;
function RealNumbersCropYield:draw()
end;
function RealNumbersCropYield:deleteMap()
end;
function RealNumbersCropYield:mouseEvent(posX, posY, isDown, isUp, button)
end;

addModEventListener(RealNumbersCropYield);
