--
-- FS19 - WorkRPM
-- This mod increases motor RPM when using hydraulics tools (moving tools), tipping, unfolding, lifting or rotating implement etc. and show RPM Hud.
-- @author:    	kenny456 (kenny456@seznam.cz) / Xentro (Marcus@Xentro.se) / Webby / [FSM]Chefkoch
-- @history:	v1.0 - 2017-11-06 - first version
--				v1.1 - 2017-11-10 - fixed slowning down vehicle when running with implement turned on
--				v1.2 - 2017-12-02 - added increase RPM when tipping
--								  - added increase RPM when folding / unfolding implement / trailer
--								  - added increase RPM to combines tipping and folding / unfolding pipe
--								  - added increase RPM when moving movingTools of attached implements / trailers
--								  - fixed slowning down machine when running with implement turned on or moving with movingTools
--				v1.3 - 2018-02-05 - added increase RPM when lifting implements attached to 3-point, which have no foldable spec. (some plows, weights, cultivators..)
--								  - added increase RPM when rotating attached implements (etc. plow)
--								  - you can deactivate increasing RPM for any action in your vehicle xml file (see readme.txt in zip)
--								  - fixed error on line 104 when you attach implement with 'foldable' specialization but with no folding animation (etc. Koeckerling Trio 300M, Amazone Cenius 3002)
--								  - fixed error on line 281 when enter to enterable trailer with no attacher vehicle connected(etc. Stepa FHL 13 AK)
--				v1.4 - 2019-01-26 - conversion to FS19
--
WorkRPM = {};
local WorkRPM_directory = g_currentModDirectory;

function WorkRPM:getTexts(i,text)
	if g_currentMission.WorkRPM == nil then
		g_currentMission.WorkRPM = {}
		g_currentMission.WorkRPM.texts = {}
	end
	g_currentMission.WorkRPM.texts[i] = text
end
EV_loaded = false
if g_modIsLoaded.TSX_EnhancedVehicle ~= nil or TSX_EnhancedVehicle ~= nil then
	EV_loaded = true
end

function WorkRPM.prerequisitesPresent(specializations)
	return true
end

function WorkRPM.initSpecialization()
end

function WorkRPM.registerOverwrittenFunctions(vehicleType)
end

function WorkRPM.registerFunctions(vehicleType)
end

function WorkRPM.registerEvents(vehicleType)
end

function WorkRPM:registerActionEventsPlayer()
end

function WorkRPM:registerActionEventsMenu()
end

function WorkRPM:onRegisterActionEvents(isSelected, isOnActiveVehicle)
	if isOnActiveVehicle then
		if self.ActionEvents == nil then 
			self.ActionEvents = {}
		else	
			self:clearActionEventsTable( self.ActionEvents )
		end 
		for _,actionName in pairs({ "WORK_RPM_LOWER", "WORK_RPM_ALLOW_TIPPING", "WORK_RPM_ALLOW_FOLDING", "WORK_RPM_ALLOW_ROTATING", "WORK_RPM_ALLOW_LIFTING", "WORK_RPM_ALLOW_MOVINGTOOLS", "WORK_RPM_ALLOW_PIPEFOLDING" } ) do
			local _, eventName = self:addActionEvent(self.ActionEvents, InputAction[actionName], self, WorkRPM.actionCallback, true, true, false, true, nil);
			if g_inputBinding ~= nil and g_inputBinding.events ~= nil and g_inputBinding.events[eventName] ~= nil then
				if isSelected then
					g_inputBinding.events[eventName].displayPriority = 1
				elseif  isOnActiveVehicle then
					g_inputBinding.events[eventName].displayPriority = 3
				end
				g_inputBinding.events[eventName].displayIsVisible = false
			end
		end
	end
end

function WorkRPM.registerEventListeners(vehicleType)
	for _,n in pairs( { "onLoad", "onPostLoad", "saveToXMLFile", "onUpdate", "onUpdateTick", "onDraw", "onReadStream", "onWriteStream", "onRegisterActionEvents" } ) do
		SpecializationUtil.registerEventListener(vehicleType, n, WorkRPM)
	end
end

function WorkRPM:onLoad(vehicle)
	self.getPtoRpm = Utils.overwrittenFunction(self.getPtoRpm, WorkRPM.getPtoRpm);
	self.getDoConsumePtoPower = Utils.overwrittenFunction(self.getDoConsumePtoPower, WorkRPM.getDoConsumePtoPower);
	local xmlFile = self.xmlFile
	self.workRpm = {};
	self.workRpm.rpm = 0;
	self.workRpm.releaseRpmTimer = 0;
	self.workRpm.maxTime = 50; -- how long rpm last after movingTool stopped
	self.workRpm.minRpm = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.motorized.motorConfigurations.motorConfiguration.motor#minRpm"), 850);
	self.workRpm.maxRpm = Utils.getNoNil(getXMLInt(self.xmlFile, "vehicle.motorized.motorConfigurations.motorConfiguration.motor#maxRpm"), 2200);
	
	if hasXMLProperty(xmlFile, 'vehicle.WorkRPM') then
		self.workRpm.rpmMovingTools = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmMovingTools"), self.workRpm.minRpm * 1.15) / 4;
		self.workRpm.rpmTipping = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmTipping"), self.workRpm.minRpm * 1.4) / 4;
		self.workRpm.rpmFolding = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmFolding"), self.workRpm.minRpm * 1.3) / 4;
		self.workRpm.rpmPipeFolding = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmPipeFolding"), self.workRpm.minRpm * 1.1) / 4;
		self.workRpm.rpmLifting = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmLifting"), self.workRpm.minRpm * 1.3) / 4;
		self.workRpm.rpmRotating = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.WorkRPM#rpmRotating"), self.workRpm.minRpm * 1.3) / 4;
	else
		self.workRpm.rpmMovingTools = (self.workRpm.minRpm * 1.15) / 4; -- how high rpm will go when movingTool move
		self.workRpm.rpmTipping = (self.workRpm.minRpm * 1.4) / 4; 		-- how high rpm will go when tipping
		self.workRpm.rpmFolding = (self.workRpm.minRpm * 1.3) / 4; 		-- how high rpm will go when folding / unfolding
		self.workRpm.rpmPipeFolding = (self.workRpm.minRpm * 1.1) / 4; 	-- how high rpm will go when pipe folding / unfolding
		self.workRpm.rpmLifting = (self.workRpm.minRpm * 1.3) / 4; 		-- how high rpm will go when lifting implement
		self.workRpm.rpmRotating = (self.workRpm.minRpm * 1.3) / 4; 	-- how high rpm will go when rotating implement
	end
	
	self.workRpm.overlay = createImageOverlay(WorkRPM_directory .. "overlay_bg.dds")
    setOverlayColor(self.workRpm.overlay, 0, 0, 0, 0.75)
	local baseX = g_currentMission.inGameMenu.hud.speedMeter.gaugeCenterX
	local baseY = g_currentMission.inGameMenu.hud.speedMeter.gaugeCenterY
    self.workRpm.posX = 0
    self.workRpm.posY = 0
    if g_currentMission.inGameMenu.hud.speedMeter.gaugeCenterX ~= nil then
      self.workRpm.posX = baseX
      self.workRpm.posY = baseY
    end
	
	self.workRpm.movingToolIds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; -- movingTool indice
    self.workRpm.neededRpmTemp = self.workRpm.minRpm / 4
	self.workRpm.inputLowerImplement = false
	self.workRpm.isFoldable = false
	self.workRpm.foldableAnim = nil
	self.workRpm.isLifting = false
	self.workRpm.liftTimer = 0
	self.workRpm.lowerInput = false
	self.workRpm.lowerInputTimer = 0
	self.workRpm.lowerInputReleased = true
	self.workRpm.allowFolding = true
	self.workRpm.allowTipping = true
	self.workRpm.allowRotating = true
	self.workRpm.allowLifting = true
	self.workRpm.allowMovingTools = true
	self.workRpm.allowPipeFolding = true
	
	if self.spec_pipe ~= nil and SpecializationUtil.hasSpecialization(Pipe, self.specializations)then
		self.workRpm.isOverloadVehicle = true
	end
	
	if SpecializationUtil.hasSpecialization(Foldable, self.specializations) then
		local anim = getXMLString(self.xmlFile, "vehicle.foldable.foldingParts.foldingPart#animationName");
		if anim ~= nil then
			self.workRpm.isFoldable = true
			self.workRpm.foldableAnim = anim
		end
	end
end

function WorkRPM:onPostLoad(savegame)
	if savegame ~= nil then
		local xmlFile = savegame.xmlFile
		local key     = savegame.key ..".WorkRPM"
		self.workRpm.allowTipping = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowTipping"), self.workRpm.allowTipping);
		self.workRpm.allowFolding = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowFolding"), self.workRpm.allowFolding);
		self.workRpm.allowRotating = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowRotating"), self.workRpm.allowRotating);
		self.workRpm.allowLifting = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowLifting"), self.workRpm.allowLifting);
		self.workRpm.allowMovingTools = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowMovingTools"), self.workRpm.allowMovingTools);
		self.workRpm.allowPipeFolding = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowPipeFolding"), self.workRpm.allowPipeFolding);
	end
end
function WorkRPM:saveToXMLFile(xmlFile, key)
	setXMLBool(xmlFile, key.."#allowTipping",    	self.workRpm.allowTipping)
	setXMLBool(xmlFile, key.."#allowFolding",     	self.workRpm.allowFolding)
	setXMLBool(xmlFile, key.."#allowRotating",      self.workRpm.allowRotating)
	setXMLBool(xmlFile, key.."#allowLifting", 		self.workRpm.allowLifting)
	setXMLBool(xmlFile, key.."#allowMovingTools", 	self.workRpm.allowMovingTools)
	setXMLBool(xmlFile, key.."#allowPipeFolding", 	self.workRpm.allowPipeFolding)
end
function WorkRPM:onUpdate(dt)
	if self:getIsActive() then
		local neededRpm = 0;
		--		Tipping		--
		if neededRpm == 0 and self.workRpm.allowTipping then
			if self.workRpm.isOverloadVehicle then
				if self.spec_dischargeable ~= nil then
					if self.spec_dischargeable.currentDischargeState == 1 or self.spec_dischargeable.currentDischargeState == 2 then
						neededRpm = self.workRpm.rpmTipping;
					end
				end
			else
				if self.spec_trailer ~= nil then
					if self.spec_trailer.tipState == Trailer.TIPSTATE_OPENING then
						neededRpm = self.workRpm.rpmTipping;
					end
				end
			end
			local trailer;
			local attVehicle
			local tempVehicle = self
			if self.spec_attacherJoints ~= nil then
				for _,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if implement.object ~= nil then
						trailer = implement.object;
						local i = 1
						while true do
							if trailer.spec_trailer ~= nil then
								if trailer.spec_pipe ~= nil and SpecializationUtil.hasSpecialization(Pipe, trailer.specializations)then
									if trailer.spec_dischargeable.currentDischargeState == 1 or trailer.spec_dischargeable.currentDischargeState == 2 then
										neededRpm = self.workRpm.rpmTipping;
										break
									end
								else
									if trailer.spec_trailer.tipState == Trailer.TIPSTATE_OPENING then
										neededRpm = self.workRpm.rpmTipping;
										break
									end
								end
							end
							if trailer.spec_attacherJoints ~= nil then
								if trailer.spec_attacherJoints.attachedImplements ~= nil then
									if trailer.spec_attacherJoints.attachedImplements[1] ~= nil then
										trailer = trailer.spec_attacherJoints.attachedImplements[1].object
									else
										break
									end
								else
									break
								end
							else
								break
							end
							i = i +1
							if i > 10 then break end
						end
					end
				end
				
			end
		end
		--		Foldable		--
		if neededRpm == 0 and self.workRpm.allowFolding then
			if self.workRpm.isFoldable == true and self.workRpm.foldableAnim ~= nil then
				if self:getIsAnimationPlaying(self.workRpm.foldableAnim) then
					neededRpm = self.workRpm.rpmFolding;
				end
			end
		end
		if neededRpm == 0 and self.workRpm.allowFolding then
			if self.spec_attacherJoints ~= nil then
				for index,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if SpecializationUtil.hasSpecialization(Foldable, implement.object.specializations) then
						local anim = getXMLString(implement.object.xmlFile, "vehicle.foldable.foldingParts.foldingPart#animationName");
						if anim ~= nil then
							implement.object.foldableAnim = anim
							if implement.object:getIsAnimationPlaying(implement.object.foldableAnim) then
								implement.object:getAnimationTime(implement.object.foldableAnim)
								neededRpm = self.workRpm.rpmFolding;
								break
							end
						end
					end
				end
			end
		end
		--		implements rotation		--
		if neededRpm == 0 and self.workRpm.allowRotating then
			if self.spec_attacherJoints ~= nil then
				for index,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if implement.object.spec_plow ~= nil then
						if implement.object.spec_plow.rotationPart ~= nil then
							if implement.object.spec_plow.rotationPart.turnAnimation ~= nil and implement.object.getAnimationTime ~= nil then
								local rotationTime = implement.object:getAnimationTime(implement.object.spec_plow.rotationPart.turnAnimation);
								if rotationTime > 0 and rotationTime < 1 then
									neededRpm = self.workRpm.rpmRotating;
									break
								end
							end
						end
					end
				end
			end
		end
		--		implements lowering / lifting		--
		if neededRpm == 0 and self.workRpm.allowLifting then
			if self.spec_attacherJoints ~= nil then
				for index,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if implement.object.spec_attachable.attacherVehicle ~= nil and implement.object.spec_attachable.attacherVehicle.spec_attacherJoints.selectedImplement ~= nil and implement.object.spec_attachable.attacherVehicle.spec_attacherJoints.attacherJoints ~= nil then
						local jointDesc = implement.object.spec_attachable.attacherVehicle.spec_attacherJoints.attacherJoints[implement.object.spec_attachable.attacherVehicle.spec_attacherJoints.selectedImplement.jointDescIndex];
						if self:getIsActive() then
							if self.workRpm.inputLowerImplement then
								self.workRpm.inputLowerImplement = false
								if self.workRpm.lowerInputReleased == true then
									self.workRpm.lowerInput = true
									self.workRpm.lowerInputReleased = false
								end
							else
								self.workRpm.lowerInputReleased = true
							end
							if self.workRpm.lowerInput == true then
								self.workRpm.lowerInputTimer = self.workRpm.lowerInputTimer + dt
								if self.workRpm.lowerInputTimer > 200 then
									self.workRpm.lowerInputTimer = 0
									self.workRpm.lowerInput = false
									if self.workRpm.jointDown == true then
										self.workRpm.isLifting = true
										self.workRpm.jointDown = false
									else
										self.workRpm.jointDown = jointDesc.moveDown
									end
								end
							else
								self.workRpm.jointDown = jointDesc.moveDown
							end
							if self.workRpm.isLifting == true then
								self.workRpm.liftTimer = self.workRpm.liftTimer + dt
								if self.workRpm.liftTimer < 1400 then
									neededRpm = self.workRpm.rpmLifting;
								else
									self.workRpm.liftTimer = 0
									self.workRpm.isLifting = false
								end
							end
						end
					end
				end
			end
		end
		--		movingTools		--
		if neededRpm == 0 and self.workRpm.allowMovingTools then
			local trailer = {}
			local vehicle = {}
			trailer.tipState = 0
			if self.spec_attacherJoints ~= nil then
				for _, attachedTrailer in pairs(self.spec_attacherJoints.attachedImplements) do
					if attachedTrailer.object ~= nil then
						if attachedTrailer.object.spec_trailer ~= nil then
							trailer = attachedTrailer.object.spec_trailer;
						end
					end
				end
			end
			if self.spec_trailer ~= nil then
				vehicle = self.spec_trailer
			end
				tcount = 0;
				if self.spec_cylindered ~= nil then
					if self.spec_cylindered.movingTools ~= 0 and self.spec_cylindered.movingTools ~= nil then
						for _ in pairs(self.spec_cylindered.movingTools) do tcount = tcount + 1 end
					end;

					for _, toolId in ipairs(self.workRpm.movingToolIds) do
						if toolId > tcount then break; end;
						local tool = self.spec_cylindered.movingTools[toolId];
						if tool.rotSpeed ~= nil then
							if tool.lastRotHistoryRPM == nil then
								tool.lastRotHistoryRPM = tool.curRot[tool.rotationAxis];
							end;
							if 0.00001 < math.abs(tool.lastRotHistoryRPM - tool.curRot[tool.rotationAxis]) and vehicle.tipState ~= 3 then
								tool.lastRotHistoryRPM = tool.curRot[tool.rotationAxis];
								neededRpm = self.workRpm.rpmMovingTools;
							end;
						end;
						if tool.transSpeed ~= nil then
							if tool.lastTransHistoryRPM == nil then
								tool.lastTransHistoryRPM = tool.curTrans[tool.translationAxis];
							end;
							if 0.00001 < math.abs(tool.lastTransHistoryRPM - tool.curTrans[tool.translationAxis]) and vehicle.tipState ~= 3 then
								tool.lastTransHistoryRPM = tool.curTrans[tool.translationAxis];
								neededRpm = self.workRpm.rpmMovingTools;
							end;
						end;
					end;
				end;
		end;
		--		implements movingTools		--
		if neededRpm == 0 and self.workRpm.allowMovingTools then
			if self.spec_attacherJoints ~= nil then
				for index,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if implement ~= nil then
						local trailer = {}
						local obj = implement.object;
						if obj.spec_trailer ~= nil then
							trailer = obj.spec_trailer;
						end
						tcount = 0;
						if obj.spec_cylindered ~= nil then
							if obj.spec_cylindered.movingTools ~= 0 and obj.spec_cylindered.movingTools ~= nil then
								for _ in pairs(obj.spec_cylindered.movingTools) do tcount = tcount + 1 end
							end
							if tcount ~= 0 then
								for _, toolId in ipairs(self.workRpm.movingToolIds) do
									if toolId > tcount then break; end;
									local tool = obj.spec_cylindered.movingTools[toolId];
									if tool.rotSpeed ~= nil then
										if tool.lastRotHistoryRPM == nil then
											tool.lastRotHistoryRPM = tool.curRot[tool.rotationAxis];
										end;
										if 0.00001 < math.abs(tool.lastRotHistoryRPM - tool.curRot[tool.rotationAxis]) and trailer.tipState ~= 3 then
											tool.lastRotHistoryRPM = tool.curRot[tool.rotationAxis];
											neededRpm = self.workRpm.rpmMovingTools;
											break
										end;
									end;
									if tool.transSpeed ~= nil then
										if tool.lastTransHistoryRPM == nil then
											tool.lastTransHistoryRPM = tool.curTrans[tool.translationAxis];
										end;
										
										if 0.00001 < math.abs(tool.lastTransHistoryRPM - tool.curTrans[tool.translationAxis]) and trailer.tipState ~= 3 then
											tool.lastTransHistoryRPM = tool.curTrans[tool.translationAxis];
											neededRpm = self.workRpm.rpmMovingTools;
											break
										end;
									end;
								end;
							end;
						end;
					end;
				end;
			end;
		end;
		--		Pipe folding / unfolding		--
		if neededRpm == 0 and self.workRpm.allowPipeFolding then
			if self.workRpm.isOverloadVehicle then
				if self.spec_pipe.currentState == 0 then
					neededRpm = self.workRpm.rpmPipeFolding;
				end
			end
		end
		if neededRpm == 0 and self.workRpm.allowPipeFolding then
			if self.spec_attacherJoints ~= nil then
				for index,implement in pairs(self.spec_attacherJoints.attachedImplements) do
					if implement.object ~= nil then
						if implement.object.spec_pipe ~= nil and SpecializationUtil.hasSpecialization(Pipe, implement.object.specializations) then
							if implement.object.spec_pipe.currentState == 0 then
								neededRpm = self.workRpm.rpmPipeFolding;
							end
						end
					end
				end
			end
		end
		if neededRpm > 0 then
			if neededRpm * 4 > self.spec_motorized.motor.lastMotorRpm then
				if self.workRpm.neededRpmTemp < neededRpm then
					self.workRpm.neededRpmBack = neededRpm
					self.workRpm.neededRpmTemp = self.workRpm.neededRpmTemp + (self.workRpm.neededRpmBack / 488.75)
				else
					self.workRpm.neededRpmTemp = neededRpm
				end
				self.workRpm.rpm = self.workRpm.neededRpmTemp;
				self.workRpm.releaseRpmTimer = g_currentMission.time + self.workRpm.maxTime;
			end
		else
			if g_currentMission.time > self.workRpm.releaseRpmTimer then
				if self.workRpm.neededRpmTemp > self.workRpm.minRpm / 4 then
					self.workRpm.neededRpmTemp = self.workRpm.neededRpmTemp - ((self.workRpm.neededRpmBack / 488.75) * 3)
					self.workRpm.rpm = self.workRpm.neededRpmTemp;
				else
					self.workRpm.neededRpmTemp = self.workRpm.minRpm / 4
					self.workRpm.rpm = 0
				end
				self.workRpm.releaseRpmTimer = 0;
			end;
		end;
	end
end
function WorkRPM:getPtoRpm(oldFunc)
	return self.workRpm.rpm;
end;
function WorkRPM:getDoConsumePtoPower(oldFunc)
	return self.workRpm.rpm > 0;
end;
function WorkRPM:onUpdateTick(dt)
end

function WorkRPM:onDraw()
	if self.isClient and self:getIsControlled() then
		if self.spec_motorized ~= nil then
			if EV_loaded and false then
				local baseX = g_currentMission.inGameMenu.hud.speedMeter.gaugeCenterX
				local baseY = g_currentMission.inGameMenu.hud.speedMeter.gaugeCenterY
				local fS = 0.0105 * g_gameSettings.uiScale
				rpm_txt = "--\nrpm"
				local w = getTextWidth(fS, rpm_txt)
				if self.spec_motorized.isMotorStarted == true then
				rpm_txt = string.format("%i\nrpm", self.spec_motorized.motor.lastMotorRpm)
				end
				if self.spec_motorized.motor.lastMotorRpm > (self.workRpm.maxRpm / 10) * 8 then
					setTextColor(1, 0, 0, 1);
				else
					setTextColor(0, 1, 0, 1);
				end
				setTextAlignment(RenderText.ALIGN_CENTER)
				setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_TOP)
				setTextBold(true)
				renderText(baseX - (g_currentMission.inGameMenu.hud.speedMeter.damageGaugeRadiusX / 1.8) + 0.0002, baseY+0.0005, fS, rpm_txt)
				renderOverlay(self.workRpm.overlay, self.workRpm.posX-0.029, self.workRpm.posY-0.024, w+0.005, 0.023)
			else
				local fs = 0.015 * g_gameSettings.uiScale
				local rpm_txt = "-- rpm"
				local w = getTextWidth(fs, rpm_txt)
				if self.spec_motorized.isMotorStarted == true then
					rpm_txt = string.format("%i rpm", self.spec_motorized.motor.lastMotorRpm)
				end
				
				if self.spec_motorized.motor.lastMotorRpm > (self.workRpm.maxRpm / 10) * 8 then
					setTextColor(1, 0, 0, 1);
				else
					setTextColor(0, 1, 0, 1);
				end
				setTextAlignment(RenderText.ALIGN_CENTER);
				setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_TOP)
				setTextBold(true);
				renderText(self.workRpm.posX, self.workRpm.posY-0.01, fs, rpm_txt)
				renderOverlay(self.workRpm.overlay, self.workRpm.posX-0.02, self.workRpm.posY-0.027, w + 0.015, 0.015)
			end
			setTextColor(1,1,1,1);
			setTextAlignment(RenderText.ALIGN_LEFT);
			setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_BASELINE)
			setTextBold(false);
		end
	end
end
function WorkRPM:actionCallback(actionName, keyStatus, arg4, arg5, arg6)
	if self:getIsActive() then
		if keyStatus > 0 then
			if actionName == 'WORK_RPM_LOWER' then
				self.workRpm.inputLowerImplement = true
			elseif actionName == 'WORK_RPM_ALLOW_TIPPING' then
				self.workRpm.allowTipping = not self.workRpm.allowTipping
				local text = self.workRpm.allowTipping and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on tipping set to '..text..' for this vehicle', 2000);
			elseif actionName == 'WORK_RPM_ALLOW_FOLDING' then
				self.workRpm.allowFolding = not self.workRpm.allowFolding
				local text = self.workRpm.allowFolding and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on folding set to '..text..' for this vehicle', 2000);
			elseif actionName == 'WORK_RPM_ALLOW_ROTATING' then
				self.workRpm.allowRotating = not self.workRpm.allowRotating
				local text = self.workRpm.allowRotating and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on rotating set to '..text..' for this vehicle', 2000);
			elseif actionName == 'WORK_RPM_ALLOW_LIFTING' then
				self.workRpm.allowLifting = not self.workRpm.allowLifting
				local text = self.workRpm.allowLifting and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on lifting set to '..text..' for this vehicle', 2000);
			elseif actionName == 'WORK_RPM_ALLOW_MOVINGTOOLS' then
				self.workRpm.allowMovingTools = not self.workRpm.allowMovingTools
				local text = self.workRpm.allowMovingTools and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on movingtools set to '..text..' for this vehicle', 2000);
			elseif actionName == 'WORK_RPM_ALLOW_PIPEFOLDING' then
				self.workRpm.allowPipeFolding = not self.workRpm.allowPipeFolding
				local text = self.workRpm.allowPipeFolding and 'ON' or 'OFF'
				g_currentMission:showBlinkingWarning('WorkRPM on pipefolding set to '..text..' for this vehicle', 2000);
			end
		elseif keyStatus == 0 then
			if actionName == 'WORK_RPM_LOWER' then
				self.workRpm.inputLowerImplement = false
			end
		end
	end
end
function WorkRPM:onReadStream(streamId, connection)
end;
function WorkRPM:onWriteStream(streamId, connection)
end;